diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 5034f8bd7bd..797c211be69 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -885,6 +885,7 @@ enum { R_MICROMIPS_HI16 = 134, R_MICROMIPS_LO16 = 135, R_MICROMIPS_GOT16 = 138, + R_MICROMIPS_PC16_S1 = 141, R_MICROMIPS_CALL16 = 142, R_MICROMIPS_GOT_DISP = 145, R_MICROMIPS_GOT_PAGE = 146, diff --git a/lib/Object/ELF.cpp b/lib/Object/ELF.cpp index 2c62eb157e7..7c80d41942f 100644 --- a/lib/Object/ELF.cpp +++ b/lib/Object/ELF.cpp @@ -165,6 +165,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_HI16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_LO16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_PC16_S1); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_CALL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_DISP); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_PAGE); diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index f9bf1aff5ee..b890d3a887c 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -205,6 +205,13 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst, uint64_t Address, const void *Decoder); +// DecodeBranchTargetMM - Decode microMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + // DecodeJumpTargetMM - Decode microMIPS jump target, which is // shifted left by 1 bit. static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, @@ -751,6 +758,16 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Offset & 0xffff; + BranchOffset = SignExtend32<18>(BranchOffset << 1); + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index b47bff66f11..3e70b23dccc 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -84,6 +84,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Mips::fixup_MICROMIPS_26_S1: Value >>= 1; break; + case Mips::fixup_MICROMIPS_PC16_S1: + Value -= 4; + Value >>= 1; + break; } return Value; @@ -201,6 +205,7 @@ public: { "fixup_MICROMIPS_HI16", 0, 16, 0 }, { "fixup_MICROMIPS_LO16", 0, 16, 0 }, { "fixup_MICROMIPS_GOT16", 0, 16, 0 }, + { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_CALL16", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 }, diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 60c9f333417..83c7d4bcc3c 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -195,6 +195,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, case Mips::fixup_MICROMIPS_GOT16: Type = ELF::R_MICROMIPS_GOT16; break; + case Mips::fixup_MICROMIPS_PC16_S1: + Type = ELF::R_MICROMIPS_PC16_S1; + break; case Mips::fixup_MICROMIPS_CALL16: Type = ELF::R_MICROMIPS_CALL16; break; diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index ab7eeada444..6ed44b74cc4 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -140,6 +140,9 @@ namespace Mips { // resulting in - R_MICROMIPS_GOT16 fixup_MICROMIPS_GOT16, + // resulting in - R_MICROMIPS_PC16_S1 + fixup_MICROMIPS_PC16_S1, + // resulting in - R_MICROMIPS_CALL16 fixup_MICROMIPS_CALL16, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index b965d134edc..79818ec0bfb 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -96,6 +96,12 @@ public: unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const; + // getBranchTargetOpValue - Return binary encoding of the microMIPS branch + // target operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups) const; + // getMachineOpValue - Return binary encoding of operand. If the machin // operand requires relocation, record the relocation and return zero. unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, @@ -276,6 +282,28 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } +/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups) const { + + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValueMM expects only expressions or immediates"); + + const MCExpr *Expr = MO.getExpr(); + Fixups.push_back(MCFixup::Create(0, Expr, + MCFixupKind(Mips:: + fixup_MICROMIPS_PC16_S1))); + return 0; +} + /// getJumpTargetOpValue - Return binary encoding of the jump /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 61a3788b90c..4981608bf24 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -238,3 +238,40 @@ class JALR_FM_MM funct> : MMArch { let Inst{15-6} = funct; let Inst{5-0} = 0x3c; } + +class BEQ_FM_MM op> : MMArch { + bits<5> rs; + bits<5> rt; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + +class BGEZ_FM_MM funct> : MMArch { + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = funct; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + +class BGEZAL_FM_MM funct> : MMArch { + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = funct; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 41273bc4de4..297b8385a71 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -20,6 +20,12 @@ def calltarget_mm : Operand { let EncoderMethod = "getJumpTargetOpValueMM"; } +def brtarget_mm : Operand { + let EncoderMethod = "getBranchTargetOpValueMM"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTargetMM"; +} + let canFoldAsLoad = 1 in class LoadLeftRightMM : @@ -177,4 +183,22 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def TAILCALL_R_MM : MMRel, JumpFR<"tcallr", GPR32Opnd, MipsTailCall>, JR_FM_MM<0x3c>, IsTailCall; def RET_MM : MMRel, RetBase<"ret", GPR32Opnd>, JR_FM_MM<0x3c>; + + /// Branch Instructions + def BEQ_MM : MMRel, CBranch<"beq", brtarget_mm, seteq, GPR32Opnd>, + BEQ_FM_MM<0x25>; + def BNE_MM : MMRel, CBranch<"bne", brtarget_mm, setne, GPR32Opnd>, + BEQ_FM_MM<0x2d>; + def BGEZ_MM : MMRel, CBranchZero<"bgez", brtarget_mm, setge, GPR32Opnd>, + BGEZ_FM_MM<0x2>; + def BGTZ_MM : MMRel, CBranchZero<"bgtz", brtarget_mm, setgt, GPR32Opnd>, + BGEZ_FM_MM<0x6>; + def BLEZ_MM : MMRel, CBranchZero<"blez", brtarget_mm, setle, GPR32Opnd>, + BGEZ_FM_MM<0x4>; + def BLTZ_MM : MMRel, CBranchZero<"bltz", brtarget_mm, setlt, GPR32Opnd>, + BGEZ_FM_MM<0x0>; + def BGEZAL_MM : MMRel, BGEZAL_FT<"bgezal", brtarget_mm, GPR32Opnd>, + BGEZAL_FM_MM<0x03>; + def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>, + BGEZAL_FM_MM<0x01>; } diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 3b74ced716a..15ef654555d 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -151,12 +151,12 @@ def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>; /// Jump and Branch Instructions let isCodeGenOnly = 1 in { def JR64 : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>; -def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>; -def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>; -def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>; -def BGTZ64 : CBranchZero<"bgtz", setgt, GPR64Opnd>, BGEZ_FM<7, 0>; -def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>; -def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>; +def BEQ64 : CBranch<"beq", brtarget, seteq, GPR64Opnd>, BEQ_FM<4>; +def BNE64 : CBranch<"bne", brtarget, setne, GPR64Opnd>, BEQ_FM<5>; +def BGEZ64 : CBranchZero<"bgez", brtarget, setge, GPR64Opnd>, BGEZ_FM<1, 1>; +def BGTZ64 : CBranchZero<"bgtz", brtarget, setgt, GPR64Opnd>, BGEZ_FM<7, 0>; +def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>; +def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>; def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM; def JALR64Pseudo : JumpLinkRegPseudo; def TAILCALL64_R : JumpFR<"tcallr", GPR64Opnd, MipsTailCall>, diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index 3c737e67de5..f4e1e1848ee 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -106,6 +106,8 @@ private: unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; unsigned getJumpTargetOpValueMM(const MachineInstr &MI, unsigned OpNo) const; + unsigned getBranchTargetOpValueMM(const MachineInstr &MI, + unsigned OpNo) const; unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; @@ -194,6 +196,12 @@ unsigned MipsCodeEmitter::getJumpTargetOpValueMM(const MachineInstr &MI, return 0; } +unsigned MipsCodeEmitter::getBranchTargetOpValueMM(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const { MachineOperand MO = MI.getOperand(OpNo); diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index c46706b1515..8f67b2e5edb 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -272,7 +272,7 @@ class SRLV_FM funct, bit rotate> : StdArch { let Inst{5-0} = funct; } -class BEQ_FM op> { +class BEQ_FM op> : StdArch { bits<5> rs; bits<5> rt; bits<16> offset; @@ -285,7 +285,7 @@ class BEQ_FM op> { let Inst{15-0} = offset; } -class BGEZ_FM op, bits<5> funct> { +class BGEZ_FM op, bits<5> funct> : StdArch { bits<5> rs; bits<16> offset; @@ -389,7 +389,7 @@ class JALR_FM : StdArch { let Inst{5-0} = 9; } -class BGEZAL_FM funct> { +class BGEZAL_FM funct> : StdArch { bits<5> rs; bits<16> offset; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index f5a519d71cc..400bee6d7eb 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -504,21 +504,24 @@ class StoreLeftRight : - InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset), +class CBranch : + InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch, - FrmI> { + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; let Defs = [AT]; } -class CBranchZero : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), +class CBranchZero : + InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> { + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -602,9 +605,9 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in { InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [], IIBranch, FrmR, opstr>; - class BGEZAL_FT : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), - !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>; + class BGEZAL_FT : + InstSE<(outs), (ins RO:$rs, opnd:$offset), + !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; } @@ -994,19 +997,23 @@ def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>; def J : MMRel, JumpFJ, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>; -def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>; +def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; +def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; +def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, + BGEZ_FM<1, 1>; +def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, + BGEZ_FM<7, 0>; +def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, + BGEZ_FM<6, 0>; +def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, + BGEZ_FM<1, 0>; def B : UncondBranch; def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; def JALR : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; def JALRPseudo : JumpLinkRegPseudo; -def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>; +def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>; +def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>; def BAL_BR : BAL_BR_Pseudo; def TAILCALL : MMRel, JumpFJ, FJ<2>, IsTailCall; diff --git a/test/MC/Disassembler/Mips/micromips.txt b/test/MC/Disassembler/Mips/micromips.txt index e82732616fc..b3de89e0eba 100644 --- a/test/MC/Disassembler/Mips/micromips.txt +++ b/test/MC/Disassembler/Mips/micromips.txt @@ -225,3 +225,27 @@ # CHECK: jr $7 0x00 0x07 0x0f 0x3c + +# CHECK: beq $9, $6, 1332 +0x94 0xc9 0x02 0x9a + +# CHECK: bgez $6, 1332 +0x40 0x46 0x02 0x9a + +# CHECK: bgezal $6, 1332 +0x40 0x66 0x02 0x9a + +# CHECK: bltzal $6, 1332 +0x40 0x26 0x02 0x9a + +# CHECK: bgtz $6, 1332 +0x40 0xc6 0x02 0x9a + +# CHECK: blez $6, 1332 +0x40 0x86 0x02 0x9a + +# CHECK: bne $9, $6, 1332 +0xb4 0xc9 0x02 0x9a + +# CHECK: bltz $6, 1332 +0x40 0x06 0x02 0x9a diff --git a/test/MC/Disassembler/Mips/micromips_le.txt b/test/MC/Disassembler/Mips/micromips_le.txt index a42bf7933c1..ec9679cb572 100644 --- a/test/MC/Disassembler/Mips/micromips_le.txt +++ b/test/MC/Disassembler/Mips/micromips_le.txt @@ -225,3 +225,27 @@ # CHECK: jr $7 0x07 0x00 0x3c 0x0f + +# CHECK: beq $9, $6, 1332 +0xc9 0x94 0x9a 0x02 + +# CHECK: bgez $6, 1332 +0x46 0x40 0x9a 0x02 + +# CHECK: bgezal $6, 1332 +0x66 0x40 0x9a 0x02 + +# CHECK: bltzal $6, 1332 +0x26 0x40 0x9a 0x02 + +# CHECK: bgtz $6, 1332 +0xc6 0x40 0x9a 0x02 + +# CHECK: blez $6, 1332 +0x86 0x40 0x9a 0x02 + +# CHECK: bne $9, $6, 1332 +0xc9 0xb4 0x9a 0x02 + +# CHECK: bltz $6, 1332 +0x06 0x40 0x9a 0x02 diff --git a/test/MC/Mips/micromips-branch-instructions.s b/test/MC/Mips/micromips-branch-instructions.s new file mode 100644 index 00000000000..84df2a17c83 --- /dev/null +++ b/test/MC/Mips/micromips-branch-instructions.s @@ -0,0 +1,65 @@ +# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \ +# RUN: | FileCheck %s -check-prefix=CHECK-EL +# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \ +# RUN: | FileCheck %s -check-prefix=CHECK-EB +# Check that the assembler can handle the documented syntax +# for arithmetic and logical instructions. +#------------------------------------------------------------------------------ +# Branch Instructions +#------------------------------------------------------------------------------ +# Little endian +#------------------------------------------------------------------------------ +# CHECK-EL: b 1332 # encoding: [0x00,0x94,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: beq $9, $6, 1332 # encoding: [0xc9,0x94,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bgez $6, 1332 # encoding: [0x46,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bgezal $6, 1332 # encoding: [0x66,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bltzal $6, 1332 # encoding: [0x26,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bgtz $6, 1332 # encoding: [0xc6,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: blez $6, 1332 # encoding: [0x86,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bne $9, $6, 1332 # encoding: [0xc9,0xb4,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bal 1332 # encoding: [0x60,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bltz $6, 1332 # encoding: [0x06,0x40,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +#------------------------------------------------------------------------------ +# Big endian +#------------------------------------------------------------------------------ +# CHECK-EB: b 1332 # encoding: [0x94,0x00,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: beq $9, $6, 1332 # encoding: [0x94,0xc9,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bgez $6, 1332 # encoding: [0x40,0x46,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bgezal $6, 1332 # encoding: [0x40,0x66,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bltzal $6, 1332 # encoding: [0x40,0x26,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bgtz $6, 1332 # encoding: [0x40,0xc6,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: blez $6, 1332 # encoding: [0x40,0x86,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bne $9, $6, 1332 # encoding: [0xb4,0xc9,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bal 1332 # encoding: [0x40,0x60,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bltz $6, 1332 # encoding: [0x40,0x06,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] + + b 1332 + beq $9,$6,1332 + bgez $6,1332 + bgezal $6,1332 + bltzal $6,1332 + bgtz $6,1332 + blez $6,1332 + bne $9,$6,1332 + bal 1332 + bltz $6,1332 diff --git a/test/MC/Mips/micromips-branch16.s b/test/MC/Mips/micromips-branch16.s new file mode 100644 index 00000000000..321ee8640f7 --- /dev/null +++ b/test/MC/Mips/micromips-branch16.s @@ -0,0 +1,69 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding \ +# RUN: -mattr=micromips | FileCheck %s -check-prefix=CHECK-FIXUP +# RUN: llvm-mc %s -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips | llvm-readobj -r \ +# RUN: | FileCheck %s -check-prefix=CHECK-ELF +#------------------------------------------------------------------------------ +# Check that the assembler can handle the documented syntax +# for relocations. +#------------------------------------------------------------------------------ +# CHECK-FIXUP: b bar # encoding: [A,0x94'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: beq $3, $4, bar # encoding: [0x83'A',0x94'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bne $3, $4, bar # encoding: [0x83'A',0xb4'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bgez $4, bar # encoding: [0x44'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bgtz $4, bar # encoding: [0xc4'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: blez $4, bar # encoding: [0x84'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bltz $4, bar # encoding: [0x04'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bgezal $4, bar # encoding: [0x64'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-FIXUP: bltzal $4, bar # encoding: [0x24'A',0x40'A',0x00,0x00] +# CHECK-FIXUP: # fixup A - offset: 0, +# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_PC16_S1 +# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00] +#------------------------------------------------------------------------------ +# Check that the appropriate relocations were created. +#------------------------------------------------------------------------------ +# CHECK-ELF: Relocations [ +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_PC16_S1 +# CHECK-ELF: ] + + b bar + beq $3, $4, bar + bne $3, $4, bar + bgez $4, bar + bgtz $4, bar + blez $4, bar + bltz $4, bar + bgezal $4, bar + bltzal $4, bar