mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-23 20:29:30 +00:00
Thumb2 assembly parsing and encoding for STR.
More addressing mode encoding bits. Handle pre increment for STR/STRB/STRH and STR(register). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139949 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4e0a55d0d1
commit
ee2c2a4f98
@ -5495,6 +5495,19 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MI->dump();
|
||||
llvm_unreachable("Unexpected instr type to insert");
|
||||
}
|
||||
// The Thumb2 pre-indexed stores have the same MI operands, they just
|
||||
// define them differently in the .td files from the isel patterns, so
|
||||
// they need pseudos.
|
||||
case ARM::t2STR_preidx:
|
||||
MI->setDesc(TII->get(ARM::t2STR_PRE));
|
||||
return BB;
|
||||
case ARM::t2STRB_preidx:
|
||||
MI->setDesc(TII->get(ARM::t2STRB_PRE));
|
||||
return BB;
|
||||
case ARM::t2STRH_preidx:
|
||||
MI->setDesc(TII->get(ARM::t2STRH_PRE));
|
||||
return BB;
|
||||
|
||||
case ARM::STRi_preidx:
|
||||
case ARM::STRBi_preidx: {
|
||||
unsigned NewOpc = MI->getOpcode() == ARM::STRi_preidx ?
|
||||
|
@ -1315,12 +1315,27 @@ def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
|
||||
|
||||
// Indexed stores
|
||||
def t2STR_PRE : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr),
|
||||
(ins rGPR:$Rt, t2addrmode_imm8:$addr),
|
||||
AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
|
||||
"str", "\t$Rt, [$Rn, $addr]!",
|
||||
"$Rn = $Rn_wb,@earlyclobber $Rn_wb",
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr))]>;
|
||||
"str", "\t$Rt, $addr!",
|
||||
"$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
|
||||
let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8";
|
||||
}
|
||||
def t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, t2addrmode_imm8:$addr),
|
||||
AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
|
||||
"strh", "\t$Rt, $addr!",
|
||||
"$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
|
||||
let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8";
|
||||
}
|
||||
|
||||
def t2STRB_PRE : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, t2addrmode_imm8:$addr),
|
||||
AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
|
||||
"strb", "\t$Rt, $addr!",
|
||||
"$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
|
||||
let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8";
|
||||
}
|
||||
|
||||
def t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
||||
@ -1332,14 +1347,6 @@ def t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(post_store rGPR:$Rt, addr_offset_none:$Rn,
|
||||
t2am_imm8_offset:$offset))]>;
|
||||
|
||||
def t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr),
|
||||
AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
|
||||
"strh", "\t$Rt, [$Rn, $addr]!",
|
||||
"$Rn = $Rn_wb,@earlyclobber $Rn_wb",
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_truncsti16 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr))]>;
|
||||
|
||||
def t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
||||
t2am_imm8_offset:$offset),
|
||||
@ -1350,14 +1357,6 @@ def t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(post_truncsti16 rGPR:$Rt, addr_offset_none:$Rn,
|
||||
t2am_imm8_offset:$offset))]>;
|
||||
|
||||
def t2STRB_PRE : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr),
|
||||
AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
|
||||
"strb", "\t$Rt, [$Rn, $addr]!",
|
||||
"$Rn = $Rn_wb,@earlyclobber $Rn_wb",
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_truncsti8 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr))]>;
|
||||
|
||||
def t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
||||
t2am_imm8_offset:$offset),
|
||||
@ -1368,6 +1367,31 @@ def t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||
(post_truncsti8 rGPR:$Rt, addr_offset_none:$Rn,
|
||||
t2am_imm8_offset:$offset))]>;
|
||||
|
||||
// Pseudo-instructions for pattern matching the pre-indexed stores. We can't
|
||||
// put the patterns on the instruction definitions directly as ISel wants
|
||||
// the address base and offset to be separate operands, not a single
|
||||
// complex operand like we represent the instructions themselves. The
|
||||
// pseudos map between the two.
|
||||
let usesCustomInserter = 1,
|
||||
Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in {
|
||||
def t2STR_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
|
||||
4, IIC_iStore_ru,
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
|
||||
def t2STRB_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
|
||||
4, IIC_iStore_ru,
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_truncsti8 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
|
||||
def t2STRH_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
|
||||
(ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
|
||||
4, IIC_iStore_ru,
|
||||
[(set GPRnopc:$Rn_wb,
|
||||
(pre_truncsti16 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
|
||||
}
|
||||
|
||||
|
||||
// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
|
||||
// only.
|
||||
// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
|
||||
|
@ -160,6 +160,8 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||
bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||
bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||
bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
|
||||
@ -2532,6 +2534,20 @@ cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
|
||||
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
||||
/// when they refer multiple MIOperands inside a single one.
|
||||
bool ARMAsmParser::
|
||||
cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
// Create a writeback register dummy placeholder.
|
||||
Inst.addOperand(MCOperand::CreateImm(0));
|
||||
((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
|
||||
((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
|
||||
((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
|
||||
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
||||
/// when they refer multiple MIOperands inside a single one.
|
||||
|
Loading…
x
Reference in New Issue
Block a user