Skip to content

Commit

Permalink
[mips][microMIPS] Implement ADDIUPC instruction
Browse files Browse the repository at this point in the history
Differential Revision: http://reviews.llvm.org/D6582

llvm-svn: 226656
  • Loading branch information
Jozef Kolek committed Jan 21, 2015
1 parent df5747a commit 2c6d732
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 0 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Expand Up @@ -1396,6 +1396,14 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
if (!isUInt<5>(Imm))
return Error(IDLoc, "immediate operand value out of range");
break;
case Mips::ADDIUPC_MM:
MCOperand Opnd = Inst.getOperand(1);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
int Imm = Opnd.getImm();
if ((Imm % 4 != 0) || !isIntN(25, Imm))
return Error(IDLoc, "immediate operand value out of range");
break;
}
}

Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
Expand Up @@ -370,6 +370,9 @@ static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);

static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);

/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
/// handle.
template <typename InsnType>
Expand Down Expand Up @@ -1756,3 +1759,9 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,

return MCDisassembler::Success;
}

static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2));
return MCDisassembler::Success;
}
12 changes: 12 additions & 0 deletions llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
Expand Up @@ -905,4 +905,16 @@ MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
}

unsigned
MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
// The immediate is encoded as 'immediate >> 2'.
unsigned Res = static_cast<unsigned>(MO.getImm());
assert((Res & 3) == 0);
return Res >> 2;
}

#include "MipsGenMCCodeEmitter.inc"
4 changes: 4 additions & 0 deletions llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
Expand Up @@ -198,6 +198,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/Mips/MicroMipsInstrFormats.td
Expand Up @@ -898,3 +898,14 @@ class BARRIER_FM_MM<bits<5> op> : MMArch {
let Inst{10-6} = 0x0;
let Inst{5-0} = 0x0;
}

class ADDIUPC_FM_MM {
bits<3> rs;
bits<23> imm;

bits<32> Inst;

let Inst{31-26} = 0x1e;
let Inst{25-23} = rs;
let Inst{22-0} = imm;
}
12 changes: 12 additions & 0 deletions llvm/lib/Target/Mips/MicroMipsInstrInfo.td
Expand Up @@ -141,6 +141,11 @@ def brtarget_mm : Operand<OtherVT> {
let DecoderMethod = "DecodeBranchTargetMM";
}

def simm23_lsl2 : Operand<i32> {
let EncoderMethod = "getSimm23Lsl2Encoding";
let DecoderMethod = "DecodeSimm23Lsl2";
}

class CompactBranchMM<string opstr, DAGOperand opnd, PatFrag cond_op,
RegisterOperand RO> :
InstSE<(outs), (ins RO:$rs, opnd:$offset),
Expand Down Expand Up @@ -422,6 +427,10 @@ class LoadWordIndexedScaledMM<string opstr, RegisterOperand RO,
InstSE<(outs RO:$rd), (ins PtrRC:$base, PtrRC:$index),
!strconcat(opstr, "\t$rd, ${index}(${base})"), [], Itin, FrmFI>;

class AddImmUPC<string opstr, RegisterOperand RO> :
InstSE<(outs RO:$rs), (ins simm23_lsl2:$imm),
!strconcat(opstr, "\t$rs, $imm"), [], NoItinerary, FrmR>;

/// A list of registers used by load/store multiple instructions.
def RegListAsmOperand : AsmOperandClass {
let Name = "RegList";
Expand Down Expand Up @@ -591,6 +600,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
def UDIV_MM : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
MULT_FM_MM<0x2ec>;

/// Arithmetic Instructions with PC and Immediate
def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM;

/// Shift Instructions
def SLL_MM : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>,
SRA_FM_MM<0, 0>;
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/Disassembler/Mips/micromips.txt
Expand Up @@ -373,6 +373,15 @@
# CHECK: nop
0x00 0x00 0x00 0x00

# CHECK: addiupc $2, 20
0x79 0x00 0x00 0x05

# CHECK: addiupc $7, 16777212
0x7b 0xbf 0xff 0xff

# CHECK: addiupc $7, -16777216
0x7b 0xc0 0x00 0x00

# CHECK: addu16 $6, $17, $4
0x07 0x42

Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/Disassembler/Mips/micromips_le.txt
Expand Up @@ -373,6 +373,15 @@
# CHECK: nop
0x00 0x00 0x00 0x00

# CHECK: addiupc $2, 20
0x00 0x79 0x05 0x00

# CHECK: addiupc $7, 16777212
0xbf 0x7b 0xff 0xff

# CHECK: addiupc $7, -16777216
0xc0 0x7b 0x00 0x00

# CHECK: addu16 $6, $17, $4
0x42 0x07

Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/Mips/micromips-alu-instructions.s
Expand Up @@ -38,6 +38,9 @@
# CHECK-EL: multu $9, $7 # encoding: [0xe9,0x00,0x3c,0x9b]
# CHECK-EL: div $zero, $9, $7 # encoding: [0xe9,0x00,0x3c,0xab]
# CHECK-EL: divu $zero, $9, $7 # encoding: [0xe9,0x00,0x3c,0xbb]
# CHECK-EL: addiupc $2, 20 # encoding: [0x00,0x79,0x05,0x00]
# CHECK-EL: addiupc $7, 16777212 # encoding: [0xbf,0x7b,0xff,0xff]
# CHECK-EL: addiupc $7, -16777216 # encoding: [0xc0,0x7b,0x00,0x00]
#------------------------------------------------------------------------------
# Big endian
#------------------------------------------------------------------------------
Expand Down Expand Up @@ -72,6 +75,9 @@
# CHECK-EB: multu $9, $7 # encoding: [0x00,0xe9,0x9b,0x3c]
# CHECK-EB: div $zero, $9, $7 # encoding: [0x00,0xe9,0xab,0x3c]
# CHECK-EB: divu $zero, $9, $7 # encoding: [0x00,0xe9,0xbb,0x3c]
# CHECK-EB: addiupc $2, 20 # encoding: [0x79,0x00,0x00,0x05]
# CHECK-EB: addiupc $7, 16777212 # encoding: [0x7b,0xbf,0xff,0xff]
# CHECK-EB: addiupc $7, -16777216 # encoding: [0x7b,0xc0,0x00,0x00]
add $9, $6, $7
add $9, $6, 17767
addu $9, $6, -15001
Expand Down Expand Up @@ -104,3 +110,6 @@
multu $9, $7
div $0, $9, $7
divu $0, $9, $7
addiupc $2, 20
addiupc $7, 16777212
addiupc $7, -16777216
3 changes: 3 additions & 0 deletions llvm/test/MC/Mips/micromips-invalid.s
Expand Up @@ -38,6 +38,9 @@
swm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
swm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $24, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
addiupc $7, 16777216 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
addiupc $6, -16777220 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
addiupc $3, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
lbu16 $9, 8($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lhu16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lw16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
Expand Down

0 comments on commit 2c6d732

Please sign in to comment.