a1f8ad145e
applied to our copy of llvm/clang. These can be applied in alphabetical order to a pristine llvm/clang 3.4 release source tree, to result in the same version used in FreeBSD. This is intended to clearly document all the changes until now, which mostly consist of cherry pickings from the respective upstream trunks, plus a number of hand-written FreeBSD-specific ones. Hopefully those can eventually be cleaned up and sent upstream too. MFC after: 1 week X-MFC-With: r263313
132 lines
5.5 KiB
Diff
132 lines
5.5 KiB
Diff
Pull in r200963 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[Sparc] Emit correct encoding for atomic instructions. Also, add support for parsing CAS instructions to test the CAS encoding.
|
|
|
|
Introduced here: http://svn.freebsd.org/changeset/base/262261
|
|
|
|
Index: test/MC/Sparc/sparc-atomic-instructions.s
|
|
===================================================================
|
|
--- test/MC/Sparc/sparc-atomic-instructions.s
|
|
+++ test/MC/Sparc/sparc-atomic-instructions.s
|
|
@@ -0,0 +1,19 @@
|
|
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
|
|
+
|
|
+ ! CHECK: membar 15 ! encoding: [0x81,0x43,0xe0,0x0f]
|
|
+ membar 15
|
|
+
|
|
+ ! CHECK: stbar ! encoding: [0x81,0x43,0xc0,0x00]
|
|
+ stbar
|
|
+
|
|
+ ! CHECK: swap [%i0+%l6], %o2 ! encoding: [0xd4,0x7e,0x00,0x16]
|
|
+ swap [%i0+%l6], %o2
|
|
+
|
|
+ ! CHECK: swap [%i0+32], %o2 ! encoding: [0xd4,0x7e,0x20,0x20]
|
|
+ swap [%i0+32], %o2
|
|
+
|
|
+ ! CHECK: cas [%i0], %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
|
|
+ cas [%i0], %l6, %o2
|
|
+
|
|
+ ! CHECK: casx [%i0], %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
|
|
+ casx [%i0], %l6, %o2
|
|
Index: lib/Target/Sparc/SparcInstrInfo.td
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcInstrInfo.td
|
|
+++ lib/Target/Sparc/SparcInstrInfo.td
|
|
@@ -935,19 +935,19 @@ let Predicates = [HasV9], hasSideEffects = 1, rd =
|
|
def MEMBARi : F3_2<2, 0b101000, (outs), (ins i32imm:$simm13),
|
|
"membar $simm13", []>;
|
|
|
|
-let Constraints = "$val = $rd" in {
|
|
+let Constraints = "$val = $dst" in {
|
|
def SWAPrr : F3_1<3, 0b001111,
|
|
- (outs IntRegs:$rd), (ins IntRegs:$val, MEMrr:$addr),
|
|
- "swap [$addr], $rd",
|
|
- [(set i32:$rd, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>;
|
|
+ (outs IntRegs:$dst), (ins MEMrr:$addr, IntRegs:$val),
|
|
+ "swap [$addr], $dst",
|
|
+ [(set i32:$dst, (atomic_swap_32 ADDRrr:$addr, i32:$val))]>;
|
|
def SWAPri : F3_2<3, 0b001111,
|
|
- (outs IntRegs:$rd), (ins IntRegs:$val, MEMri:$addr),
|
|
- "swap [$addr], $rd",
|
|
- [(set i32:$rd, (atomic_swap_32 ADDRri:$addr, i32:$val))]>;
|
|
+ (outs IntRegs:$dst), (ins MEMri:$addr, IntRegs:$val),
|
|
+ "swap [$addr], $dst",
|
|
+ [(set i32:$dst, (atomic_swap_32 ADDRri:$addr, i32:$val))]>;
|
|
}
|
|
|
|
let Predicates = [HasV9], Constraints = "$swap = $rd" in
|
|
- def CASrr: F3_1<3, 0b111100,
|
|
+ def CASrr: F3_1_asi<3, 0b111100, 0b10000000,
|
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
|
|
IntRegs:$swap),
|
|
"cas [$rs1], $rs2, $rd",
|
|
Index: lib/Target/Sparc/SparcInstrFormats.td
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcInstrFormats.td
|
|
+++ lib/Target/Sparc/SparcInstrFormats.td
|
|
@@ -100,9 +100,8 @@ class F3<dag outs, dag ins, string asmstr, list<da
|
|
|
|
// Specific F3 classes: SparcV8 manual, page 44
|
|
//
|
|
-class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
|
|
+class F3_1_asi<bits<2> opVal, bits<6> op3val, bits<8> asi, dag outs, dag ins,
|
|
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
|
|
- bits<8> asi = 0; // asi not currently used
|
|
bits<5> rs2;
|
|
|
|
let op = opVal;
|
|
@@ -113,6 +112,10 @@ class F3<dag outs, dag ins, string asmstr, list<da
|
|
let Inst{4-0} = rs2;
|
|
}
|
|
|
|
+class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins, string asmstr,
|
|
+ list<dag> pattern> : F3_1_asi<opVal, op3val, 0, outs, ins,
|
|
+ asmstr, pattern>;
|
|
+
|
|
class F3_2<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
|
|
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
|
|
bits<13> simm13;
|
|
Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
@@ -546,7 +546,24 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*>
|
|
Parser.getTok().getLoc()));
|
|
Parser.Lex(); // Eat the [
|
|
|
|
- ResTy = parseMEMOperand(Operands);
|
|
+ if (Mnemonic == "cas" || Mnemonic == "casx") {
|
|
+ SMLoc S = Parser.getTok().getLoc();
|
|
+ if (getLexer().getKind() != AsmToken::Percent)
|
|
+ return MatchOperand_NoMatch;
|
|
+ Parser.Lex(); // eat %
|
|
+
|
|
+ unsigned RegNo, RegKind;
|
|
+ if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
|
|
+ return MatchOperand_NoMatch;
|
|
+
|
|
+ Parser.Lex(); // Eat the identifier token.
|
|
+ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
|
|
+ Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
|
|
+ ResTy = MatchOperand_Success;
|
|
+ } else {
|
|
+ ResTy = parseMEMOperand(Operands);
|
|
+ }
|
|
+
|
|
if (ResTy != MatchOperand_Success)
|
|
return ResTy;
|
|
|
|
Index: lib/Target/Sparc/SparcInstr64Bit.td
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcInstr64Bit.td
|
|
+++ lib/Target/Sparc/SparcInstr64Bit.td
|
|
@@ -415,7 +415,7 @@ def SETHIXi : F2_1<0b100,
|
|
|
|
// ATOMICS.
|
|
let Predicates = [Is64Bit], Constraints = "$swap = $rd" in {
|
|
- def CASXrr: F3_1<3, 0b111110,
|
|
+ def CASXrr: F3_1_asi<3, 0b111110, 0b10000000,
|
|
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
|
|
I64Regs:$swap),
|
|
"casx [$rs1], $rs2, $rd",
|