Index: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -285,6 +285,9 @@ static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't /// handle. template @@ -1197,3 +1200,9 @@ Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) << 2)); return MCDisassembler::Success; } + +static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) << 3)); + return MCDisassembler::Success; +} Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -141,6 +141,10 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -628,4 +628,15 @@ return Res >> 2; } +unsigned +MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(MI.getOperand(OpNo).isImm()); + // The immediate is encoded as 'immediate << 3'. + unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); + assert((Res & 7) == 0); + return Res >> 3; +} + #include "MipsGenMCCodeEmitter.inc" Index: llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td +++ llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td @@ -48,6 +48,11 @@ def OPCODE2_LWPC : OPCODE2<0b01>; def OPCODE2_LWUPC : OPCODE2<0b10>; +class OPCODE3 Val> { + bits<3> Value = Val; +} +def OPCODE3_LDPC : OPCODE3<0b110>; + class OPCODE5 Val> { bits<5> Value = Val; } @@ -216,6 +221,18 @@ let Inst{18-0} = imm; } +class PCREL18_FM : MipsR6Inst { + bits<5> rs; + bits<18> imm; + + bits<32> Inst; + + let Inst{31-26} = OPGROUP_PCREL.Value; + let Inst{25-21} = rs; + let Inst{20-18} = Operation.Value; + let Inst{17-0} = imm; +} + class SPECIAL3_2R_FM : MipsR6Inst { bits<5> rd; bits<5> rt; Index: llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td @@ -241,16 +241,17 @@ // //===----------------------------------------------------------------------===// -class PCREL19_DESC_BASE { +class PCREL_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rs); - dag InOperandList = (ins simm19_lsl2:$imm); + dag InOperandList = (ins ImmOpnd:$imm); string AsmString = !strconcat(instr_asm, "\t$rs, $imm"); list Pattern = []; } -class ADDIUPC_DESC : PCREL19_DESC_BASE<"addiupc", GPR32Opnd>; -class LWPC_DESC: PCREL19_DESC_BASE<"lwpc", GPR32Opnd>; -class LWUPC_DESC: PCREL19_DESC_BASE<"lwupc", GPR32Opnd>; +class ADDIUPC_DESC : PCREL_DESC_BASE<"addiupc", GPR32Opnd, simm19_lsl2>; +class LWPC_DESC: PCREL_DESC_BASE<"lwpc", GPR32Opnd, simm19_lsl2>; +class LWUPC_DESC: PCREL_DESC_BASE<"lwupc", GPR32Opnd, simm19_lsl2>; class ALIGN_DESC_BASE { Index: llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td @@ -37,6 +37,7 @@ class DMUHU_ENC : SPECIAL_3R_FM<0b00011, 0b111001>; class DMUL_R6_ENC : SPECIAL_3R_FM<0b00010, 0b111000>; class DMULU_ENC : SPECIAL_3R_FM<0b00010, 0b111001>; +class LDPC_ENC : PCREL18_FM; //===----------------------------------------------------------------------===// // @@ -64,6 +65,7 @@ class DMUHU_DESC : MUL_R6_DESC_BASE<"dmuhu", GPR64Opnd>; class DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd>; class DMULU_DESC : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd>; +class LDPC_DESC : PCREL_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3>; //===----------------------------------------------------------------------===// // @@ -85,4 +87,4 @@ def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6; def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; -def LDPC; +def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6; Index: llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp +++ llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp @@ -124,6 +124,7 @@ unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLSAImmEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getSimm19Lsl2Encoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getSimm18Lsl3Encoding(const MachineInstr &MI, unsigned OpNo) const; /// Expand pseudo instructions with accumulator register operands. void expandACCInstr(MachineBasicBlock::instr_iterator MI, @@ -273,6 +274,12 @@ return 0; } +unsigned MipsCodeEmitter::getSimm18Lsl3Encoding(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + unsigned MipsCodeEmitter::getSimm19Lsl2Encoding(const MachineInstr &MI, unsigned OpNo) const { llvm_unreachable("Unimplemented function."); Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -339,6 +339,11 @@ let DecoderMethod = "DecodeSimm19Lsl2"; } +def simm18_lsl3 : Operand { + let EncoderMethod = "getSimm18Lsl3Encoding"; + let DecoderMethod = "DecodeSimm18Lsl3"; +} + def simm20 : Operand { } Index: llvm/trunk/test/MC/Disassembler/Mips/mips64r6.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/mips64r6.txt +++ llvm/trunk/test/MC/Disassembler/Mips/mips64r6.txt @@ -127,3 +127,4 @@ 0x46 0x20 0x20 0x9a # CHECK: rint.d $f2, $f4 0x46 0x00 0x20 0x9b # CHECK: class.s $f2, $f4 0x46 0x20 0x20 0x9b # CHECK: class.d $f2, $f4 +0xec 0x58 0x3c 0x48 # CHECK: ldpc $2, 123456 Index: llvm/trunk/test/MC/Mips/mips64r6/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64r6/valid.s +++ llvm/trunk/test/MC/Mips/mips64r6/valid.s @@ -103,6 +103,7 @@ ddivu $2,$3,$4 # CHECK: ddivu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9f] dmod $2,$3,$4 # CHECK: dmod $2, $3, $4 # encoding: [0x00,0x64,0x10,0xde] dmodu $2,$3,$4 # CHECK: dmodu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xdf] + ldpc $2,123456 # CHECK: ldpc $2, 123456 # encoding: [0xec,0x58,0x3c,0x48] lwpc $2,268 # CHECK: lwpc $2, 268 # encoding: [0xec,0x48,0x00,0x43] lwupc $2,268 # CHECK: lwupc $2, 268 # encoding: [0xec,0x50,0x00,0x43] # mul $2,$3,$4 # CHECK-TODO: mul $2, $3, $4 # encoding: [0x00,0x64,0x10,0x98]