[Sparc] Add return/rett instruction to Sparc backend.
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>
Sun, 2 Mar 2014 22:55:53 +0000 (22:55 +0000)
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>
Sun, 2 Mar 2014 22:55:53 +0000 (22:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202666 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
lib/Target/Sparc/SparcInstrAliases.td
lib/Target/Sparc/SparcInstrInfo.td
test/MC/Disassembler/Sparc/sparc.txt
test/MC/Sparc/sparc-ctrl-instructions.s
test/MC/Sparc/sparc64-ctrl-instructions.s

index 901560c5c97cdcea2a7ed6e26a07e64a28341995..2ff6cdd8f43950a7e9f7534bceb538225f5ba616 100644 (file)
@@ -446,6 +446,9 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
   return Error(StartLoc, "invalid register name");
 }
 
+static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
+                                 unsigned VariantID);
+
 bool SparcAsmParser::
 ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                  SMLoc NameLoc,
@@ -455,6 +458,9 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
   // First operand in MCInst is instruction mnemonic.
   Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
 
+  // apply mnemonic aliases, if any, so that we can parse operands correctly.
+  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
+
   if (getLexer().isNot(AsmToken::EndOfStatement)) {
     // Read the first operand.
     if (getLexer().is(AsmToken::Comma)) {
index ea4d6da3ebe460f8e78923b6e812aad3e791d1e7..df2d3798a24206600e47e9481770de7e198bd210 100644 (file)
@@ -209,6 +209,8 @@ static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
                                  uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
                                const void *Decoder);
+static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
+                                 const void *Decoder);
 
 #include "SparcGenDisassemblerTables.inc"
 
@@ -415,3 +417,31 @@ static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
   }
   return MCDisassembler::Success;
 }
+
+static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
+                                 const void *Decoder) {
+
+  unsigned rs1 = fieldFromInstruction(insn, 14, 5);
+  unsigned isImm = fieldFromInstruction(insn, 13, 1);
+  unsigned rs2 = 0;
+  unsigned simm13 = 0;
+  if (isImm)
+    simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
+  else
+    rs2 = fieldFromInstruction(insn, 0, 5);
+
+  // Decode RS1.
+  DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
+  if (status != MCDisassembler::Success)
+    return status;
+
+  // Decode RS2 | SIMM13.
+  if (isImm)
+    MI.addOperand(MCOperand::CreateImm(simm13));
+  else {
+    status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
+    if (status != MCDisassembler::Success)
+      return status;
+  }
+  return MCDisassembler::Success;
+}
index a77f248e43e7ded8d24222734a8bb54066d37376..974fa849f22c41a60db87194796e95db286237be 100644 (file)
@@ -249,6 +249,8 @@ def : InstAlias<"mov $simm13, $rd", (ORri IntRegs:$rd, G0, i32imm:$simm13)>;
 // restore -> restore %g0, %g0, %g0
 def : InstAlias<"restore", (RESTORErr G0, G0, G0)>;
 
+def : MnemonicAlias<"return", "rett">, Requires<[HasV9]>;
+
 def : MnemonicAlias<"addc", "addx">, Requires<[HasV9]>;
 def : MnemonicAlias<"addccc", "addxcc">, Requires<[HasV9]>;
 
index 11e3c7467ddff2dc793575bbdb3b5c2ec3601bbc..9de8f3790d5eec08f62a9733218f6a27521aaf3f 100644 (file)
@@ -406,6 +406,14 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
                   "jmp %i7+$val", []>;
 }
 
+let isReturn = 1, isTerminator = 1, hasDelaySlot = 1,
+     isBarrier = 1, rd = 0, DecoderMethod = "DecodeReturn" in {
+  def RETTrr : F3_1<2, 0b111001, (outs), (ins MEMrr:$addr),
+                       "rett $addr", []>;
+  def RETTri : F3_2<2, 0b111001, (outs), (ins MEMri:$addr),
+                       "rett $addr", []>;
+}
+
 // Section B.1 - Load Integer Instructions, p. 90
 let DecoderMethod = "DecodeLoadInt" in {
   defm LDSB : Load<"ldsb", 0b001001, sextloadi8,  IntRegs, i32>;
index 289c738800ff86ebf24d2c1895bbf56f6aef425e..a9420246361fb22dac5d2a455132a2ac50199984 100644 (file)
 
 # CHECK: ret
 0x81,0xc7,0xe0,0x08
+
+# CHECK:  rett %i7+8
+0x81 0xcf 0xe0 0x08
index ac4ead1ee04fad7eb5ba3aa5498f87142dd74507..cf92e7045d43b7a57e6d2597e296610c1ce0acc3 100644 (file)
         ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
         fbo,a .BB0
 
+        ! CHECK:  rett %i7+8   ! encoding: [0x81,0xcf,0xe0,0x08]
+        rett %i7 + 8
index d3f633daf3fa6e7ccda475b2287c07d98b520702..1484e0c84c15629c99ea154295446e8d7e30c10e 100644 (file)
         fmovrsnz  %g1, %f2, %f3
         fmovrsgz  %g1, %f2, %f3
         fmovrsgez %g1, %f2, %f3
+
+        ! CHECK:  rett %i7+8   ! encoding: [0x81,0xcf,0xe0,0x08]
+        return %i7 + 8