mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-15 05:25:55 +00:00
Add a new addressing mode for NEON load/store instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74658 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4434ed44c4
commit
8b024a5eb5
@ -497,6 +497,28 @@ namespace ARM_AM {
|
|||||||
return ((AM5Opc >> 8) & 1);
|
return ((AM5Opc >> 8) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// Addressing Mode #6
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This is used for NEON load / store instructions.
|
||||||
|
//
|
||||||
|
// addrmode6 := reg with optional writeback
|
||||||
|
//
|
||||||
|
// This is stored in three operands [regaddr, regupdate, opc]. The first is
|
||||||
|
// the address register. The second register holds the value of a post-access
|
||||||
|
// increment for writeback or reg0 if no writeback or if the writeback
|
||||||
|
// increment is the size of the memory access. The third operand encodes
|
||||||
|
// whether there is writeback to the address register.
|
||||||
|
|
||||||
|
static inline unsigned getAM6Opc(bool WB = false) {
|
||||||
|
return (int)WB;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool getAM6WBFlag(unsigned Mode) {
|
||||||
|
return Mode & 1;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace ARM_AM
|
} // end namespace ARM_AM
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
|
@ -462,6 +462,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn,
|
|||||||
Bits = 8;
|
Bits = 8;
|
||||||
Scale = 4; // +-(offset_8*4)
|
Scale = 4; // +-(offset_8*4)
|
||||||
break;
|
break;
|
||||||
|
// addrmode6 has no immediate offset.
|
||||||
case ARMII::AddrModeT1_1:
|
case ARMII::AddrModeT1_1:
|
||||||
Bits = 5; // +offset_5
|
Bits = 5; // +offset_5
|
||||||
break;
|
break;
|
||||||
|
@ -76,6 +76,8 @@ public:
|
|||||||
SDValue &Offset, SDValue &Opc);
|
SDValue &Offset, SDValue &Opc);
|
||||||
bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
|
bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
|
||||||
SDValue &Offset);
|
SDValue &Offset);
|
||||||
|
bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update,
|
||||||
|
SDValue &Opc);
|
||||||
|
|
||||||
bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
|
bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
|
||||||
SDValue &Label);
|
SDValue &Label);
|
||||||
@ -105,7 +107,6 @@ public:
|
|||||||
bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base,
|
bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base,
|
||||||
SDValue &OffReg, SDValue &ShImm);
|
SDValue &OffReg, SDValue &ShImm);
|
||||||
|
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
#include "ARMGenDAGISel.inc"
|
#include "ARMGenDAGISel.inc"
|
||||||
|
|
||||||
@ -415,6 +416,16 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N,
|
||||||
|
SDValue &Addr, SDValue &Update,
|
||||||
|
SDValue &Opc) {
|
||||||
|
Addr = N;
|
||||||
|
// The optional writeback is handled in ARMLoadStoreOpt.
|
||||||
|
Update = CurDAG->getRegister(0, MVT::i32);
|
||||||
|
Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
|
bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
|
||||||
SDValue &Offset, SDValue &Label) {
|
SDValue &Offset, SDValue &Label) {
|
||||||
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
|
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
|
||||||
|
@ -72,15 +72,16 @@ def AddrMode2 : AddrMode<2>;
|
|||||||
def AddrMode3 : AddrMode<3>;
|
def AddrMode3 : AddrMode<3>;
|
||||||
def AddrMode4 : AddrMode<4>;
|
def AddrMode4 : AddrMode<4>;
|
||||||
def AddrMode5 : AddrMode<5>;
|
def AddrMode5 : AddrMode<5>;
|
||||||
def AddrModeT1_1 : AddrMode<6>;
|
def AddrMode6 : AddrMode<6>;
|
||||||
def AddrModeT1_2 : AddrMode<7>;
|
def AddrModeT1_1 : AddrMode<7>;
|
||||||
def AddrModeT1_4 : AddrMode<8>;
|
def AddrModeT1_2 : AddrMode<8>;
|
||||||
def AddrModeT1_s : AddrMode<9>;
|
def AddrModeT1_4 : AddrMode<9>;
|
||||||
def AddrModeT2_i12: AddrMode<10>;
|
def AddrModeT1_s : AddrMode<10>;
|
||||||
def AddrModeT2_i8 : AddrMode<11>;
|
def AddrModeT2_i12: AddrMode<12>;
|
||||||
def AddrModeT2_so : AddrMode<12>;
|
def AddrModeT2_i8 : AddrMode<12>;
|
||||||
def AddrModeT2_pc : AddrMode<13>;
|
def AddrModeT2_so : AddrMode<13>;
|
||||||
def AddrModeT2_i8s4 : AddrMode<14>;
|
def AddrModeT2_pc : AddrMode<14>;
|
||||||
|
def AddrModeT2_i8s4 : AddrMode<15>;
|
||||||
|
|
||||||
// Instruction size.
|
// Instruction size.
|
||||||
class SizeFlagVal<bits<3> val> {
|
class SizeFlagVal<bits<3> val> {
|
||||||
|
@ -39,15 +39,16 @@ namespace ARMII {
|
|||||||
AddrMode3 = 3,
|
AddrMode3 = 3,
|
||||||
AddrMode4 = 4,
|
AddrMode4 = 4,
|
||||||
AddrMode5 = 5,
|
AddrMode5 = 5,
|
||||||
AddrModeT1_1 = 6,
|
AddrMode6 = 6,
|
||||||
AddrModeT1_2 = 7,
|
AddrModeT1_1 = 7,
|
||||||
AddrModeT1_4 = 8,
|
AddrModeT1_2 = 8,
|
||||||
AddrModeT1_s = 9, // i8 * 4 for pc and sp relative data
|
AddrModeT1_4 = 9,
|
||||||
AddrModeT2_i12 = 10,
|
AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
|
||||||
AddrModeT2_i8 = 11,
|
AddrModeT2_i12 = 11,
|
||||||
AddrModeT2_so = 12,
|
AddrModeT2_i8 = 12,
|
||||||
AddrModeT2_pc = 13, // +/- i12 for pc relative data
|
AddrModeT2_so = 13,
|
||||||
AddrModeT2_i8s4 = 14, // i8 * 4
|
AddrModeT2_pc = 14, // +/- i12 for pc relative data
|
||||||
|
AddrModeT2_i8s4 = 15, // i8 * 4
|
||||||
|
|
||||||
// Size* - Flags to keep track of the size of an instruction.
|
// Size* - Flags to keep track of the size of an instruction.
|
||||||
SizeShift = 4,
|
SizeShift = 4,
|
||||||
|
@ -287,6 +287,14 @@ def addrmode5 : Operand<i32>,
|
|||||||
let MIOperandInfo = (ops GPR, i32imm);
|
let MIOperandInfo = (ops GPR, i32imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addrmode6 := reg with optional writeback
|
||||||
|
//
|
||||||
|
def addrmode6 : Operand<i32>,
|
||||||
|
ComplexPattern<i32, 3, "SelectAddrMode6", []> {
|
||||||
|
let PrintMethod = "printAddrMode6Operand";
|
||||||
|
let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm);
|
||||||
|
}
|
||||||
|
|
||||||
// addrmodepc := pc + reg
|
// addrmodepc := pc + reg
|
||||||
//
|
//
|
||||||
def addrmodepc : Operand<i32>,
|
def addrmodepc : Operand<i32>,
|
||||||
|
@ -105,6 +105,7 @@ namespace {
|
|||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
|
void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
|
||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
|
void printAddrMode6Operand(const MachineInstr *MI, int OpNum);
|
||||||
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
|
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
|
||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
|
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
|
||||||
@ -587,6 +588,22 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
|
|||||||
O << "]";
|
O << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
|
||||||
|
const MachineOperand &MO1 = MI->getOperand(Op);
|
||||||
|
const MachineOperand &MO2 = MI->getOperand(Op+1);
|
||||||
|
const MachineOperand &MO3 = MI->getOperand(Op+2);
|
||||||
|
|
||||||
|
// FIXME: No support yet for specifying alignment.
|
||||||
|
O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
|
||||||
|
|
||||||
|
if (ARM_AM::getAM6WBFlag(MO3.getImm())) {
|
||||||
|
if (MO2.getReg() == 0)
|
||||||
|
O << "!";
|
||||||
|
else
|
||||||
|
O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
|
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
|
||||||
const char *Modifier) {
|
const char *Modifier) {
|
||||||
if (Modifier && strcmp(Modifier, "label") == 0) {
|
if (Modifier && strcmp(Modifier, "label") == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user