Mips assembler: .set reorder support

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
This commit is contained in:
Jack Carter 2013-04-25 23:31:35 +00:00
parent 0fc7137f2f
commit 97265a4889
2 changed files with 31 additions and 0 deletions

View 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.

View 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