| ... | @@ -5432,6 +5432,25 @@ pub const FuncGen = struct { | ... | @@ -5432,6 +5432,25 @@ pub const FuncGen = struct { |
| 5432 | total_i += 1; | 5432 | total_i += 1; |
| 5433 | } | 5433 | } |
| 5434 | } | 5434 | } |
| | 5435 | |
| | 5436 | // For some targets, Clang unconditionally adds some clobbers to all inline assembly. |
| | 5437 | // While this is probably not strictly necessary, if we don't follow Clang's lead |
| | 5438 | // here then we may risk tripping LLVM bugs since anything not used by Clang tends |
| | 5439 | // to be buggy and regress often. |
| | 5440 | switch (target.cpu.arch) { |
| | 5441 | .x86_64, .i386 => { |
| | 5442 | if (total_i != 0) try llvm_constraints.append(self.gpa, ','); |
| | 5443 | try llvm_constraints.appendSlice(self.gpa, "~{dirflag},~{fpsr},~{flags}"); |
| | 5444 | total_i += 3; |
| | 5445 | }, |
| | 5446 | .mips, .mipsel, .mips64, .mips64el => { |
| | 5447 | if (total_i != 0) try llvm_constraints.append(self.gpa, ','); |
| | 5448 | try llvm_constraints.appendSlice(self.gpa, "~{$1}"); |
| | 5449 | total_i += 1; |
| | 5450 | }, |
| | 5451 | else => {}, |
| | 5452 | } |
| | 5453 | |
| 5435 | const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; | 5454 | const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; |
| 5436 | | 5455 | |
| 5437 | // hackety hacks until stage2 has proper inline asm in the frontend. | 5456 | // hackety hacks until stage2 has proper inline asm in the frontend. |