def pci : T2Ipc <(outs target:$Rt), (ins t2ldrlabel:$addr), iii,
opc, ".w\t$Rt, $addr",
[(set target:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
- bits<4> Rt;
- bits<13> addr;
let isReMaterializable = 1;
let Inst{31-27} = 0b11111;
let Inst{26-25} = 0b00;
let Inst{24} = signed;
- let Inst{23} = addr{12}; // add = (U == '1')
let Inst{22-21} = opcod;
let Inst{20} = 1; // load
let Inst{19-16} = 0b1111; // Rn
+
+ bits<4> Rt;
let Inst{15-12} = Rt{3-0};
+
+ bits<13> addr;
+ let Inst{23} = addr{12}; // add = (U == '1')
let Inst{11-0} = addr{11-0};
let DecoderMethod = "DecodeT2LoadLabel";
Sched<[WritePreLd]> {
let Inst{31-25} = 0b1111100;
let Inst{24} = instr;
+ let Inst{23} = 1;
let Inst{22} = 0;
let Inst{21} = write;
let Inst{20} = 1;
let Inst{15-12} = 0b1111;
bits<17> addr;
- let addr{12} = 1; // add = TRUE
let Inst{19-16} = addr{16-13}; // Rn
- let Inst{23} = addr{12}; // U
let Inst{11-0} = addr{11-0}; // imm12
+
+ let DecoderMethod = "DecodeT2LoadImm12";
}
def i8 : T2Ii8<(outs), (ins t2addrmode_negimm8:$addr), IIC_Preload, opc,
bits<13> addr;
let Inst{19-16} = addr{12-9}; // Rn
let Inst{7-0} = addr{7-0}; // imm8
+
+ let DecoderMethod = "DecodeT2LoadImm8";
}
def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
let Inst{21} = write;
let Inst{20} = 1;
let Inst{15-12} = 0b1111;
- let Inst{11-6} = 0000000;
+ let Inst{11-6} = 0b000000;
bits<10> addr;
let Inst{19-16} = addr{9-6}; // Rn
let DecoderMethod = "DecodeT2LoadShift";
}
- // FIXME: We should have a separate 'pci' variant here. As-is we represent
- // it via the i12 variant, which it's related to, but that means we can
- // represent negative immediates, which aren't legal for anything except
- // the 'pci' case (Rn == 15).
+
+ // pci variant is very similar to i12, but supports negative offsets
+ // from the PC.
+ def pci : T2Iso<(outs), (ins t2ldrlabel:$addr), IIC_Preload, opc,
+ "\t$addr",
+ [(ARMPreload (ARMWrapper tconstpool:$addr),
+ (i32 write), (i32 instr))]>,
+ Sched<[WritePreLd]> {
+ let Inst{31-25} = 0b1111100;
+ let Inst{24} = instr;
+ let Inst{22} = 0;
+ let Inst{21} = write;
+ let Inst{20} = 1;
+ let Inst{19-16} = 0b1111;
+ let Inst{15-12} = 0b1111;
+
+ bits<13> addr;
+ let Inst{23} = addr{12}; // add = (U == '1')
+ let Inst{11-0} = addr{11-0}; // imm12
+
+ let DecoderMethod = "DecodeT2LoadLabel";
+ }
}
defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
unsigned Rt = fieldFromInstruction(Insn, 12, 4);
unsigned Rn = fieldFromInstruction(Insn, 16, 4);
- if (Rn == 0xF) {
+ if (Rn == 15) {
switch (Inst.getOpcode()) {
- case ARM::t2LDRBs:
- Inst.setOpcode(ARM::t2LDRBpci);
- break;
- case ARM::t2LDRHs:
- Inst.setOpcode(ARM::t2LDRHpci);
- break;
- case ARM::t2LDRSHs:
- Inst.setOpcode(ARM::t2LDRSHpci);
- break;
- case ARM::t2LDRSBs:
- Inst.setOpcode(ARM::t2LDRSBpci);
- break;
- case ARM::t2LDRs:
- Inst.setOpcode(ARM::t2LDRpci);
- break;
- case ARM::t2PLDs: {
- Inst.setOpcode(ARM::t2PLDi12);
- Inst.addOperand(MCOperand::CreateReg(ARM::PC));
- int imm = fieldFromInstruction(Insn, 0, 12);
- if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1;
- Inst.addOperand(MCOperand::CreateImm(imm));
- return S;
- }
- default:
- return MCDisassembler::Fail;
+ case ARM::t2LDRBs:
+ Inst.setOpcode(ARM::t2LDRBpci);
+ break;
+ case ARM::t2LDRHs:
+ Inst.setOpcode(ARM::t2LDRHpci);
+ break;
+ case ARM::t2LDRSHs:
+ Inst.setOpcode(ARM::t2LDRSHpci);
+ break;
+ case ARM::t2LDRSBs:
+ Inst.setOpcode(ARM::t2LDRSBpci);
+ break;
+ case ARM::t2LDRs:
+ Inst.setOpcode(ARM::t2LDRpci);
+ break;
+ case ARM::t2PLDs:
+ Inst.setOpcode(ARM::t2PLDpci);
+ break;
+ case ARM::t2PLIs:
+ Inst.setOpcode(ARM::t2PLIpci);
+ break;
+ default:
+ return MCDisassembler::Fail;
}
return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
}
+ if (Rt == 15) {
+ switch (Inst.getOpcode()) {
+ case ARM::t2LDRSHs:
+ return MCDisassembler::Fail;
+ case ARM::t2LDRHs:
+ // FIXME: this instruction is only available with MP extensions,
+ // this should be checked first but we don't have access to the
+ // feature bits here.
+ Inst.setOpcode(ARM::t2PLDWs);
+ break;
+ default:
+ break;
+ }
+ }
+
switch (Inst.getOpcode()) {
case ARM::t2PLDs:
case ARM::t2PLDWs:
case ARM::t2LDRSHi8:
Inst.setOpcode(ARM::t2LDRSHpci);
break;
+ case ARM::t2PLDi8:
+ Inst.setOpcode(ARM::t2PLDpci);
+ break;
+ case ARM::t2PLIi8:
+ Inst.setOpcode(ARM::t2PLIpci);
+ break;
default:
return MCDisassembler::Fail;
}
return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
}
- if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
- return MCDisassembler::Fail;
+ if (Rt == 15) {
+ switch (Inst.getOpcode()) {
+ case ARM::t2LDRSHi8:
+ return MCDisassembler::Fail;
+ default:
+ break;
+ }
+ }
+
+ switch (Inst.getOpcode()) {
+ case ARM::t2PLDi8:
+ case ARM::t2PLIi8:
+ break;
+ default:
+ if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
+ return MCDisassembler::Fail;
+ }
+
if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
return MCDisassembler::Fail;
return S;
case ARM::t2LDRSBi12:
Inst.setOpcode(ARM::t2LDRSBpci);
break;
+ case ARM::t2PLDi12:
+ Inst.setOpcode(ARM::t2PLDpci);
+ break;
+ case ARM::t2PLIi12:
+ Inst.setOpcode(ARM::t2PLIpci);
+ break;
default:
return MCDisassembler::Fail;
}
return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
}
- if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
- return MCDisassembler::Fail;
+ if (Rt == 15) {
+ switch (Inst.getOpcode()) {
+ case ARM::t2LDRSHi12:
+ return MCDisassembler::Fail;
+ case ARM::t2LDRHi12:
+ Inst.setOpcode(ARM::t2PLDi12);
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (Inst.getOpcode()) {
+ case ARM::t2PLDi12:
+ case ARM::t2PLIi12:
+ break;
+ default:
+ if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
+ return MCDisassembler::Fail;
+ }
+
if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
return MCDisassembler::Fail;
return S;
unsigned U = fieldFromInstruction(Insn, 23, 1);
int imm = fieldFromInstruction(Insn, 0, 12);
- // FIXME: detect and decode PLD properly
- if (Inst.getOpcode() == ARM::t2LDRBpci && Rt == 15) {
- Inst.setOpcode(ARM::t2PLDi12);
- Inst.addOperand(MCOperand::CreateReg(ARM::PC));
- } else {
+ if (Rt == 15) {
+ switch (Inst.getOpcode()) {
+ case ARM::t2LDRBpci:
+ case ARM::t2LDRHpci:
+ Inst.setOpcode(ARM::t2PLDpci);
+ break;
+ case ARM::t2LDRSBpci:
+ Inst.setOpcode(ARM::t2PLIpci);
+ break;
+ case ARM::t2LDRSHpci:
+ return MCDisassembler::Fail;
+ default:
+ break;
+ }
+ }
+
+ switch(Inst.getOpcode()) {
+ case ARM::t2PLDpci:
+ case ARM::t2PLIpci:
+ break;
+ default:
if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
return MCDisassembler::Fail;
}
break;
case ARM::t2LDRSB_PRE:
case ARM::t2LDRSB_POST:
- Inst.setOpcode(ARM::t2LDRSBpci);
+ if (Rt == 15)
+ Inst.setOpcode(ARM::t2PLIpci);
+ else
+ Inst.setOpcode(ARM::t2LDRSBpci);
break;
case ARM::t2LDRSH_PRE:
case ARM::t2LDRSH_POST: