Mips assembler: .set reorder support
authorJack Carter <jack.carter@imgtec.com>
Thu, 25 Apr 2013 23:31:35 +0000 (23:31 +0000)
committerJack Carter <jack.carter@imgtec.com>
Thu, 25 Apr 2013 23:31:35 +0000 (23:31 +0000)
Mips have delayslots for certain instructions
like jumps and branches. These are instructions
that follow the branch or jump and are executed
before the jump or branch is completed.

Early Mips compilers could not cope with delayslots
and left them up to the assembler. The assembler would
fill the delayslots with the appropriate instruction,
usually just a nop to allow correct runtime behavior.

The default behavior for this is set with .set reorder.
To tell the assembler that you don't want it to mess with
the delayslot one used .set noreorder.

For backwards compatibility we need to support
.set reorder and have it be the default behavior in the
assembler.

Our support for it is to insert a NOP directly after an
instruction with a delayslot when in .set reorder mode.

Contributer: Vladimir Medic

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180584 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
test/MC/Mips/mips_directives.s

index befc573826e08c10cbd6e4b02025e9b4a2b4ee05..0795cb963b35bff2b1bdae77d0eea2fe425d649c 100644 (file)
@@ -418,6 +418,19 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
                                        SmallVectorImpl<MCInst> &Instructions) {
   const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
   Inst.setLoc(IDLoc);
+  if (MCID.hasDelaySlot() && Options.isReorder()) {
+    // If this instruction has a delay slot and .set reorder is active,
+    // emit a NOP after it.
+    Instructions.push_back(Inst);
+    MCInst NopInst;
+    NopInst.setOpcode(Mips::SLL);
+    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
+    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
+    NopInst.addOperand(MCOperand::CreateImm(0));
+    Instructions.push_back(NopInst);
+    return false;
+  }
+
   if (MCID.mayLoad() || MCID.mayStore()) {
     // Check the offset of memory operand, if it is a symbol
     // reference or immediate we may have to expand instructions.
index df7e64563371f4e90e34382d03c9c78361ecb2cc..45247cd162b53180a85644ec9452b7d2b29461c5 100644 (file)
@@ -1,11 +1,20 @@
 # RUN: llvm-mc -show-encoding -triple mips-unknown-unknown %s | FileCheck %s
 #
+# CHECK:  .text
+# CHECK:  $BB0_2:
 $BB0_2:
   .ent directives_test
     .frame    $sp,0,$ra
     .mask     0x00000000,0
     .fmask    0x00000000,0
+# CHECK:   b 1332               # encoding: [0x10,0x00,0x01,0x4d]
+# CHECK:   j 1328               # encoding: [0x08,0x00,0x01,0x4c]
+# CHECK:   jal 1328             # encoding: [0x0c,0x00,0x01,0x4c]
+
     .set    noreorder
+     b 1332
+     j 1328
+     jal 1328
     .set    nomacro
     .set    noat
 $JTI0_0:
@@ -15,7 +24,16 @@ $JTI0_0:
 # CHECK-NEXT:     .4byte    2013265916
     .set  at=$12
     .set macro
+# CHECK:   b 1332               # encoding: [0x10,0x00,0x01,0x4d]
+# CHECK:   nop                  # encoding: [0x00,0x00,0x00,0x00]
+# CHECK:   j 1328               # encoding: [0x08,0x00,0x01,0x4c]
+# CHECK:   nop                  # encoding: [0x00,0x00,0x00,0x00]
+# CHECK:   jal 1328             # encoding: [0x0c,0x00,0x01,0x4c]
+# CHECK:   nop                  # encoding: [0x00,0x00,0x00,0x00]
     .set reorder
+    b 1332
+    j 1328
+    jal 1328
     .set  at=$a0
     .set STORE_MASK,$t7
     .set FPU_MASK,$f7