summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2015-05-18 16:38:47 +0000
committerJames Y Knight <jyknight@google.com>2015-05-18 16:38:47 +0000
commitf7e7017281738ac64bb137d8900f96fe9c7fbc21 (patch)
tree6fddd9a37683e0752daa5786e8096f4f2dbddb9f
parent24060be73ac17046cdd05c384ed23aa346148f3c (diff)
downloadbcm5719-llvm-f7e7017281738ac64bb137d8900f96fe9c7fbc21.tar.gz
bcm5719-llvm-f7e7017281738ac64bb137d8900f96fe9c7fbc21.zip
Sparc: Support PSR, TBR, WIM read/write instructions.
Differential Revision: http://reviews.llvm.org/D8971 llvm-svn: 237582
-rw-r--r--llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp42
-rw-r--r--llvm/lib/Target/Sparc/SparcInstrInfo.td48
-rw-r--r--llvm/lib/Target/Sparc/SparcRegisterInfo.td5
-rw-r--r--llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt34
-rw-r--r--llvm/test/MC/Disassembler/Sparc/sparc.txt15
-rw-r--r--llvm/test/MC/Sparc/sparc-special-registers.s18
6 files changed, 139 insertions, 23 deletions
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 84cb440e742..a2d46b657a6 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -144,9 +144,9 @@ public:
rk_FloatReg,
rk_DoubleReg,
rk_QuadReg,
- rk_CCReg,
- rk_ASRReg
+ rk_Special,
};
+
private:
enum KindTy {
k_Token,
@@ -679,7 +679,15 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
default:
Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
break;
-
+ case Sparc::PSR:
+ Op = SparcOperand::CreateToken("%psr", S);
+ break;
+ case Sparc::WIM:
+ Op = SparcOperand::CreateToken("%wim", S);
+ break;
+ case Sparc::TBR:
+ Op = SparcOperand::CreateToken("%tbr", S);
+ break;
case Sparc::ICC:
if (name == "xcc")
Op = SparcOperand::CreateToken("%xcc", S);
@@ -768,7 +776,7 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
if (name.equals("y")) {
RegNo = Sparc::Y;
- RegKind = SparcOperand::rk_ASRReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
@@ -776,20 +784,38 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
&& !name.substr(3).getAsInteger(10, intVal)
&& intVal > 0 && intVal < 32) {
RegNo = ASRRegs[intVal];
- RegKind = SparcOperand::rk_ASRReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
if (name.equals("icc")) {
RegNo = Sparc::ICC;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("psr")) {
+ RegNo = Sparc::PSR;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("wim")) {
+ RegNo = Sparc::WIM;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("tbr")) {
+ RegNo = Sparc::TBR;
+ RegKind = SparcOperand::rk_Special;
return true;
}
if (name.equals("xcc")) {
// FIXME:: check 64bit.
RegNo = Sparc::ICC;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
@@ -799,7 +825,7 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
&& intVal < 4) {
// FIXME: check 64bit and handle %fcc1 - %fcc3
RegNo = Sparc::FCC0 + intVal;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 732ec360100..b1f795b81e8 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -731,6 +731,24 @@ let rs2 = 0 in
(outs IntRegs:$rd), (ins ASRRegs:$rs1),
"rd $rs1, $rd", []>;
+// PSR, WIM, and TBR don't exist on the SparcV9, only the V8.
+let Predicates = [HasNoV9] in {
+ let rs2 = 0, rs1 = 0, Uses=[PSR] in
+ def RDPSR : F3_1<2, 0b101001,
+ (outs IntRegs:$rd), (ins),
+ "rd %psr, $rd", []>;
+
+ let rs2 = 0, rs1 = 0, Uses=[WIM] in
+ def RDWIM : F3_1<2, 0b101010,
+ (outs IntRegs:$rd), (ins),
+ "rd %wim, $rd", []>;
+
+ let rs2 = 0, rs1 = 0, Uses=[TBR] in
+ def RDTBR : F3_1<2, 0b101011,
+ (outs IntRegs:$rd), (ins),
+ "rd %tbr, $rd", []>;
+}
+
// Section B.29 - Write State Register Instructions
def WRASRrr : F3_1<2, 0b110000,
(outs ASRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
@@ -739,6 +757,36 @@ def WRASRri : F3_2<2, 0b110000,
(outs ASRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13),
"wr $rs1, $simm13, $rd", []>;
+// PSR, WIM, and TBR don't exist on the SparcV9, only the V8.
+let Predicates = [HasNoV9] in {
+ let Defs = [PSR], rd=0 in {
+ def WRPSRrr : F3_1<2, 0b110001,
+ (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
+ "wr $rs1, $rs2, %psr", []>;
+ def WRPSRri : F3_2<2, 0b110001,
+ (outs), (ins IntRegs:$rs1, simm13Op:$simm13),
+ "wr $rs1, $simm13, %psr", []>;
+ }
+
+ let Defs = [WIM], rd=0 in {
+ def WRWIMrr : F3_1<2, 0b110010,
+ (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
+ "wr $rs1, $rs2, %wim", []>;
+ def WRWIMri : F3_2<2, 0b110010,
+ (outs), (ins IntRegs:$rs1, simm13Op:$simm13),
+ "wr $rs1, $simm13, %wim", []>;
+ }
+
+ let Defs = [TBR], rd=0 in {
+ def WRTBRrr : F3_1<2, 0b110011,
+ (outs), (ins IntRegs:$rs1, IntRegs:$rs2),
+ "wr $rs1, $rs2, %tbr", []>;
+ def WRTBRri : F3_2<2, 0b110011,
+ (outs), (ins IntRegs:$rs1, simm13Op:$simm13),
+ "wr $rs1, $simm13, %tbr", []>;
+ }
+}
+
// Convert Integer to Floating-point Instructions, p. 141
def FITOS : F3_3u<2, 0b110100, 0b011000100,
(outs FPRegs:$rd), (ins FPRegs:$rs2),
diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.td b/llvm/lib/Target/Sparc/SparcRegisterInfo.td
index 0c12399e360..e504da4d3b2 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.td
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.td
@@ -89,6 +89,11 @@ def ASR29 : SparcCtrlReg<29, "ASR29">;
def ASR30 : SparcCtrlReg<30, "ASR30">;
def ASR31 : SparcCtrlReg<31, "ASR31">;
+// Note that PSR, WIM, and TBR don't exist on the SparcV9, only the V8.
+def PSR : SparcCtrlReg<0, "PSR">;
+def WIM : SparcCtrlReg<0, "WIM">;
+def TBR : SparcCtrlReg<0, "TBR">;
+
// Integer registers
def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>;
def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>;
diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
new file mode 100644
index 00000000000..f653dbda605
--- /dev/null
+++ b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
@@ -0,0 +1,34 @@
+# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s
+
+# CHECK: wr %g1, -2, %y
+0x81 0x80 0x7f 0xfe
+
+# 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: rd %psr, %i0
+0xb1 0x48 0x00 0x00
+
+# CHECK: rd %wim, %i0
+0xb1 0x50 0x00 0x00
+
+# CHECK: rd %tbr, %i0
+0xb1 0x58 0x00 0x00
+
+# CHECK: wr %i0, 5, %psr
+0x81 0x8e 0x20 0x05
+
+# CHECK: wr %i0, 5, %wim
+0x81 0x96 0x20 0x05
+
+# CHECK: wr %i0, 5, %tbr
+0x81 0x9e 0x20 0x05
diff --git a/llvm/test/MC/Disassembler/Sparc/sparc.txt b/llvm/test/MC/Disassembler/Sparc/sparc.txt
index 038aef53d51..6724ebf8bf2 100644
--- a/llvm/test/MC/Disassembler/Sparc/sparc.txt
+++ b/llvm/test/MC/Disassembler/Sparc/sparc.txt
@@ -183,9 +183,6 @@
# CHECK: cmp %g1, -2
0x80 0xa0 0x7f 0xfe
-# CHECK: wr %g1, -2, %y
-0x81 0x80 0x7f 0xfe
-
# CHECK: unimp 12
0x00 0x00 0x00 0x0c
@@ -201,17 +198,5 @@
# 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
diff --git a/llvm/test/MC/Sparc/sparc-special-registers.s b/llvm/test/MC/Sparc/sparc-special-registers.s
index 74e4fc6350b..2cb57d720c4 100644
--- a/llvm/test/MC/Sparc/sparc-special-registers.s
+++ b/llvm/test/MC/Sparc/sparc-special-registers.s
@@ -15,3 +15,21 @@
! CHECK: rd %asr15, %g0 ! encoding: [0x81,0x43,0xc0,0x00]
rd %asr15, %g0
+
+ ! CHECK: rd %psr, %i0 ! encoding: [0xb1,0x48,0x00,0x00]
+ rd %psr, %i0
+
+ ! CHECK: rd %wim, %i0 ! encoding: [0xb1,0x50,0x00,0x00]
+ rd %wim, %i0
+
+ ! CHECK: rd %tbr, %i0 ! encoding: [0xb1,0x58,0x00,0x00]
+ rd %tbr, %i0
+
+ ! CHECK: wr %i0, 5, %psr ! encoding: [0x81,0x8e,0x20,0x05]
+ wr %i0, 5, %psr
+
+ ! CHECK: wr %i0, 5, %wim ! encoding: [0x81,0x96,0x20,0x05]
+ wr %i0, 5, %wim
+
+ ! CHECK: wr %i0, 5, %tbr ! encoding: [0x81,0x9e,0x20,0x05]
+ wr %i0, 5, %tbr
OpenPOWER on IntegriCloud