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();
|
MI->dump();
|
||||||
llvm_unreachable("Unexpected instr type to insert");
|
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::STRi_preidx:
|
||||||
case ARM::STRBi_preidx: {
|
case ARM::STRBi_preidx: {
|
||||||
unsigned NewOpc = MI->getOpcode() == ARM::STRi_preidx ?
|
unsigned NewOpc = MI->getOpcode() == ARM::STRi_preidx ?
|
||||||
|
@ -1315,12 +1315,27 @@ def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
|
|||||||
|
|
||||||
// Indexed stores
|
// Indexed stores
|
||||||
def t2STR_PRE : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb),
|
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,
|
AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
|
||||||
"str", "\t$Rt, [$Rn, $addr]!",
|
"str", "\t$Rt, $addr!",
|
||||||
"$Rn = $Rn_wb,@earlyclobber $Rn_wb",
|
"$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> {
|
||||||
[(set GPRnopc:$Rn_wb,
|
let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8";
|
||||||
(pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$addr))]>;
|
}
|
||||||
|
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),
|
def t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
(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,
|
(post_store rGPR:$Rt, addr_offset_none:$Rn,
|
||||||
t2am_imm8_offset:$offset))]>;
|
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),
|
def t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
||||||
t2am_imm8_offset:$offset),
|
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,
|
(post_truncsti16 rGPR:$Rt, addr_offset_none:$Rn,
|
||||||
t2am_imm8_offset:$offset))]>;
|
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),
|
def t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb),
|
||||||
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
(ins rGPR:$Rt, addr_offset_none:$Rn,
|
||||||
t2am_imm8_offset:$offset),
|
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,
|
(post_truncsti8 rGPR:$Rt, addr_offset_none:$Rn,
|
||||||
t2am_imm8_offset:$offset))]>;
|
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
|
// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
|
||||||
// only.
|
// only.
|
||||||
// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
|
// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
|
||||||
|
@ -160,6 +160,8 @@ class ARMAsmParser : public MCTargetAsmParser {
|
|||||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
|
bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
||||||
|
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
||||||
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
const SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
|
bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
|
||||||
@ -2532,6 +2534,20 @@ cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
|
|||||||
return true;
|
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.
|
/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
|
||||||
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
|
||||||
/// when they refer multiple MIOperands inside a single one.
|
/// when they refer multiple MIOperands inside a single one.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user