[llvm] r237580 - Add support for the Sparc implementation-defined "ASR" registers.
James Y Knight
jyknight at google.com
Mon May 18 09:29:48 PDT 2015
Author: jyknight
Date: Mon May 18 11:29:48 2015
New Revision: 237580
URL: http://llvm.org/viewvc/llvm-project?rev=237580&view=rev
Log:
Add support for the Sparc implementation-defined "ASR" registers.
(Note that register "Y" is essentially just ASR0).
Also added some test cases for divide and multiply, which had none before.
Differential Revision: http://reviews.llvm.org/D8670
Added:
llvm/trunk/test/MC/Sparc/sparc-special-registers.s
Modified:
llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp
llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td
llvm/trunk/test/CodeGen/SPARC/basictest.ll
llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt
Modified: llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp Mon May 18 11:29:48 2015
@@ -124,6 +124,15 @@ public:
Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
+ static unsigned ASRRegs[32] = {
+ SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
+ SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
+ SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
+ SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
+ SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
+ SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
+ SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
+ SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
/// SparcOperand - Instances of this class represent a parsed Sparc machine
/// instruction.
@@ -136,7 +145,7 @@ public:
rk_DoubleReg,
rk_QuadReg,
rk_CCReg,
- rk_Y
+ rk_ASRReg
};
private:
enum KindTy {
@@ -661,9 +670,6 @@ SparcAsmParser::parseSparcAsmOperand(std
default:
Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
break;
- case Sparc::Y:
- Op = SparcOperand::CreateToken("%y", S);
- break;
case Sparc::ICC:
if (name == "xcc")
@@ -753,7 +759,15 @@ bool SparcAsmParser::matchRegisterName(c
if (name.equals("y")) {
RegNo = Sparc::Y;
- RegKind = SparcOperand::rk_Y;
+ RegKind = SparcOperand::rk_ASRReg;
+ return true;
+ }
+
+ if (name.substr(0, 3).equals_lower("asr")
+ && !name.substr(3).getAsInteger(10, intVal)
+ && intVal > 0 && intVal < 32) {
+ RegNo = ASRRegs[intVal];
+ RegKind = SparcOperand::rk_ASRReg;
return true;
}
Modified: llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp Mon May 18 11:29:48 2015
@@ -107,6 +107,16 @@ static const unsigned QFPRegDecoderTable
static const unsigned FCCRegDecoderTable[] = {
SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
+static const unsigned ASRRegDecoderTable[] = {
+ SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
+ SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
+ SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
+ SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
+ SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
+ SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
+ SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
+ SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
+
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@@ -177,6 +187,15 @@ static DecodeStatus DecodeFCCRegsRegiste
return MCDisassembler::Success;
}
+static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+ Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Mon May 18 11:29:48 2015
@@ -168,8 +168,10 @@ SDNode *SparcDAGToDAGISel::Select(SDNode
} else {
TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
}
- TopPart = SDValue(CurDAG->getMachineNode(SP::WRYrr, dl, MVT::Glue, TopPart,
- CurDAG->getRegister(SP::G0, MVT::i32)), 0);
+ TopPart = SDValue(CurDAG->getMachineNode(SP::WRASRrr, dl, MVT::i32,
+ TopPart,
+ CurDAG->getRegister(SP::G0, MVT::i32)), 0);
+ TopPart = CurDAG->getCopyToReg(TopPart, dl, SP::Y, TopPart, SDValue()).getValue(1);
// FIXME: Handle div by immediate.
unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
@@ -185,7 +187,9 @@ SDNode *SparcDAGToDAGISel::Select(SDNode
SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
MulLHS, MulRHS);
// The high part is in the Y register.
- return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDValue(Mul, 1));
+ return CurDAG->SelectNodeTo(N, SP::RDASR, MVT::i32,
+ CurDAG->getRegister(SP::Y, MVT::i32),
+ SDValue(Mul, 1));
}
}
Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Mon May 18 11:29:48 2015
@@ -705,20 +705,19 @@ let Uses = [O6],
}
// Section B.28 - Read State Register Instructions
-let Uses = [Y], rs1 = 0, rs2 = 0 in
- def RDY : F3_1<2, 0b101000,
- (outs IntRegs:$dst), (ins),
- "rd %y, $dst", []>;
+let rs2 = 0 in
+ def RDASR : F3_1<2, 0b101000,
+ (outs IntRegs:$rd), (ins ASRRegs:$rs1),
+ "rd $rs1, $rd", []>;
// Section B.29 - Write State Register Instructions
-let Defs = [Y], rd = 0 in {
- def WRYrr : F3_1<2, 0b110000,
- (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
- "wr $rs1, $rs2, %y", []>;
- def WRYri : F3_2<2, 0b110000,
- (outs), (ins IntRegs:$rs1, simm13Op:$simm13),
- "wr $rs1, $simm13, %y", []>;
-}
+def WRASRrr : F3_1<2, 0b110000,
+ (outs ASRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
+ "wr $rs1, $rs2, $rd", []>;
+def WRASRri : F3_2<2, 0b110000,
+ (outs ASRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13),
+ "wr $rs1, $simm13, $rd", []>;
+
// Convert Integer to Floating-point Instructions, p. 141
def FITOS : F3_3u<2, 0b110100, 0b011000100,
(outs FPRegs:$rd), (ins FPRegs:$rs2),
Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Mon May 18 11:29:48 2015
@@ -56,6 +56,38 @@ foreach I = 0-3 in
// Y register
def Y : SparcCtrlReg<0, "Y">, DwarfRegNum<[64]>;
+// Ancillary state registers (implementation defined)
+def ASR1 : SparcCtrlReg<1, "ASR1">;
+def ASR2 : SparcCtrlReg<2, "ASR2">;
+def ASR3 : SparcCtrlReg<3, "ASR3">;
+def ASR4 : SparcCtrlReg<4, "ASR4">;
+def ASR5 : SparcCtrlReg<5, "ASR5">;
+def ASR6 : SparcCtrlReg<6, "ASR6">;
+def ASR7 : SparcCtrlReg<7, "ASR7">;
+def ASR8 : SparcCtrlReg<8, "ASR8">;
+def ASR9 : SparcCtrlReg<9, "ASR9">;
+def ASR10 : SparcCtrlReg<10, "ASR10">;
+def ASR11 : SparcCtrlReg<11, "ASR11">;
+def ASR12 : SparcCtrlReg<12, "ASR12">;
+def ASR13 : SparcCtrlReg<13, "ASR13">;
+def ASR14 : SparcCtrlReg<14, "ASR14">;
+def ASR15 : SparcCtrlReg<15, "ASR15">;
+def ASR16 : SparcCtrlReg<16, "ASR16">;
+def ASR17 : SparcCtrlReg<17, "ASR17">;
+def ASR18 : SparcCtrlReg<18, "ASR18">;
+def ASR19 : SparcCtrlReg<19, "ASR19">;
+def ASR20 : SparcCtrlReg<20, "ASR20">;
+def ASR21 : SparcCtrlReg<21, "ASR21">;
+def ASR22 : SparcCtrlReg<22, "ASR22">;
+def ASR23 : SparcCtrlReg<23, "ASR23">;
+def ASR24 : SparcCtrlReg<24, "ASR24">;
+def ASR25 : SparcCtrlReg<25, "ASR25">;
+def ASR26 : SparcCtrlReg<26, "ASR26">;
+def ASR27 : SparcCtrlReg<27, "ASR27">;
+def ASR28 : SparcCtrlReg<28, "ASR28">;
+def ASR29 : SparcCtrlReg<29, "ASR29">;
+def ASR30 : SparcCtrlReg<30, "ASR30">;
+def ASR31 : SparcCtrlReg<31, "ASR31">;
// Integer registers
def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>;
@@ -209,3 +241,7 @@ def QFPRegs : RegisterClass<"SP", [f128]
// Floating point control register classes.
def FCCRegs : RegisterClass<"SP", [i1], 1, (sequence "FCC%u", 0, 3)>;
+
+// Ancillary state registers
+def ASRRegs : RegisterClass<"SP", [i32], 32,
+ (add Y, (sequence "ASR%u", 1, 31))>;
Modified: llvm/trunk/test/CodeGen/SPARC/basictest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/basictest.ll?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/basictest.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/basictest.ll Mon May 18 11:29:48 2015
@@ -36,3 +36,51 @@ entry:
ret i32 0
}
+; CHECK-LABEL: signed_divide:
+; CHECK: sra %o0, 31, %o2
+; CHECK: wr %o2, %g0, %y
+; CHECK: sdiv %o0, %o1, %o0
+define i32 @signed_divide(i32 %a, i32 %b) {
+ %r = sdiv i32 %a, %b
+ ret i32 %r
+}
+
+; CHECK-LABEL: unsigned_divide:
+; CHECK: wr %g0, %g0, %y
+; CHECK: udiv %o0, %o1, %o0
+define i32 @unsigned_divide(i32 %a, i32 %b) {
+ %r = udiv i32 %a, %b
+ ret i32 %r
+}
+
+; CHECK-LABEL: multiply_32x32:
+; CHECK: smul %o0, %o1, %o0
+define i32 @multiply_32x32(i32 %a, i32 %b) {
+ %r = mul i32 %a, %b
+ ret i32 %r
+}
+
+; CHECK-LABEL: signed_multiply_32x32_64:
+; CHECK: smul %o0, %o1, %o1
+; CHECK: rd %y, %o0
+define i64 @signed_multiply_32x32_64(i32 %a, i32 %b) {
+ %xa = sext i32 %a to i64
+ %xb = sext i32 %b to i64
+ %r = mul i64 %xa, %xb
+ ret i64 %r
+}
+
+; CHECK-LABEL: unsigned_multiply_32x32_64:
+; CHECK: umul %o0, %o1, %o2
+; CHECK: rd %y, %o2
+;FIXME: the smul in the output is totally redundant and should not there.
+; CHECK: smul %o0, %o1, %o1
+; CHECK: retl
+; CHECK: mov %o2, %o0
+define i64 @unsigned_multiply_32x32_64(i32 %a, i32 %b) {
+ %xa = zext i32 %a to i64
+ %xb = zext i32 %b to i64
+ %r = mul i64 %xa, %xb
+ ret i64 %r
+}
+
Modified: llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt?rev=237580&r1=237579&r2=237580&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt Mon May 18 11:29:48 2015
@@ -200,3 +200,18 @@
# CHECK: rett %i7+8
0x81 0xcf 0xe0 0x08
+
+# CHECK: rd %y, %i0
+0xb1 0x40 0x00 0x00
+
+# CHECK: rd %asr1, %i0
+0xb1 0x40 0x40 0x00
+
+# CHECK: wr %i0, 5, %y
+0x81 0x86 0x20 0x05
+
+# CHECK: wr %i0, %i1, %asr15
+0x9f 0x86 0x00 0x19
+
+# CHECK: stbar
+0x81 0x43 0xc0 0x00
Added: llvm/trunk/test/MC/Sparc/sparc-special-registers.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Sparc/sparc-special-registers.s?rev=237580&view=auto
==============================================================================
--- llvm/trunk/test/MC/Sparc/sparc-special-registers.s (added)
+++ llvm/trunk/test/MC/Sparc/sparc-special-registers.s Mon May 18 11:29:48 2015
@@ -0,0 +1,17 @@
+! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
+
+ ! CHECK: rd %y, %i0 ! encoding: [0xb1,0x40,0x00,0x00]
+ rd %y, %i0
+
+ ! CHECK: rd %asr1, %i0 ! encoding: [0xb1,0x40,0x40,0x00]
+ rd %asr1, %i0
+
+ ! CHECK: wr %i0, 5, %y ! encoding: [0x81,0x86,0x20,0x05]
+ wr %i0, 5, %y
+
+ ! CHECK: wr %i0, %i1, %asr15 ! encoding: [0x9f,0x86,0x00,0x19]
+ wr %i0, %i1, %asr15
+
+ ! CHECK: rd %asr15, %g0 ! encoding: [0x81,0x43,0xc0,0x00]
+ rd %asr15, %g0
More information about the llvm-commits
mailing list