mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-24 03:25:00 +00:00
Encode VFP load / store instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59084 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b13af2f2ec
commit
cd8e66a1ef
@ -124,6 +124,12 @@ namespace {
|
|||||||
|
|
||||||
void emitVFPConversionInstruction(const MachineInstr &MI);
|
void emitVFPConversionInstruction(const MachineInstr &MI);
|
||||||
|
|
||||||
|
void emitVFPLoadStoreInstruction(const MachineInstr &MI);
|
||||||
|
|
||||||
|
void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI);
|
||||||
|
|
||||||
|
void emitMiscInstruction(const MachineInstr &MI);
|
||||||
|
|
||||||
/// getBinaryCodeForInstr - This function, generated by the
|
/// getBinaryCodeForInstr - This function, generated by the
|
||||||
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
|
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
|
||||||
/// machine instructions.
|
/// machine instructions.
|
||||||
@ -326,6 +332,15 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
case ARMII::VFPConv2Frm:
|
case ARMII::VFPConv2Frm:
|
||||||
emitVFPConversionInstruction(MI);
|
emitVFPConversionInstruction(MI);
|
||||||
break;
|
break;
|
||||||
|
case ARMII::VFPLdStFrm:
|
||||||
|
emitVFPLoadStoreInstruction(MI);
|
||||||
|
break;
|
||||||
|
case ARMII::VFPLdStMulFrm:
|
||||||
|
emitVFPLoadStoreMultipleInstruction(MI);
|
||||||
|
break;
|
||||||
|
case ARMII::VFPMiscFrm:
|
||||||
|
emitMiscInstruction(MI);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,23 +774,14 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
|
|||||||
emitWordLE(Binary);
|
emitWordLE(Binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
static unsigned getAddrModeUPBits(unsigned Mode) {
|
||||||
// Part of binary is determined by TableGn.
|
unsigned Binary = 0;
|
||||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
|
||||||
|
|
||||||
// Set the conditional execution predicate
|
|
||||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
|
||||||
|
|
||||||
// Set first operand
|
|
||||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
|
|
||||||
|
|
||||||
// Set addressing mode by modifying bits U(23) and P(24)
|
// Set addressing mode by modifying bits U(23) and P(24)
|
||||||
// IA - Increment after - bit U = 1 and bit P = 0
|
// IA - Increment after - bit U = 1 and bit P = 0
|
||||||
// IB - Increment before - bit U = 1 and bit P = 1
|
// IB - Increment before - bit U = 1 and bit P = 1
|
||||||
// DA - Decrement after - bit U = 0 and bit P = 0
|
// DA - Decrement after - bit U = 0 and bit P = 0
|
||||||
// DB - Decrement before - bit U = 0 and bit P = 1
|
// DB - Decrement before - bit U = 0 and bit P = 1
|
||||||
const MachineOperand &MO = MI.getOperand(1);
|
|
||||||
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm());
|
|
||||||
switch (Mode) {
|
switch (Mode) {
|
||||||
default: assert(0 && "Unknown addressing sub-mode!");
|
default: assert(0 && "Unknown addressing sub-mode!");
|
||||||
case ARM_AM::da: break;
|
case ARM_AM::da: break;
|
||||||
@ -784,6 +790,23 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
|||||||
case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
|
case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Binary;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||||
|
// Part of binary is determined by TableGn.
|
||||||
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
|
|
||||||
|
// Set the conditional execution predicate
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
// Set base address operand
|
||||||
|
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
|
||||||
|
|
||||||
|
// Set addressing mode by modifying bits U(23) and P(24)
|
||||||
|
const MachineOperand &MO = MI.getOperand(1);
|
||||||
|
Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm()));
|
||||||
|
|
||||||
// Set bit W(21)
|
// Set bit W(21)
|
||||||
if (ARM_AM::getAM4WBFlag(MO.getImm()))
|
if (ARM_AM::getAM4WBFlag(MO.getImm()))
|
||||||
Binary |= 0x1 << ARMII::W_BitShift;
|
Binary |= 0x1 << ARMII::W_BitShift;
|
||||||
@ -791,8 +814,8 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
|||||||
// Set registers
|
// Set registers
|
||||||
for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) {
|
for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI.getOperand(i);
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
if (MO.isReg() && MO.isImplicit())
|
if (!MO.isReg() || MO.isImplicit())
|
||||||
continue;
|
break;
|
||||||
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(MO.getReg());
|
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
||||||
RegNum < 16);
|
RegNum < 16);
|
||||||
@ -1064,4 +1087,87 @@ void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
|
|||||||
emitWordLE(Binary);
|
emitWordLE(Binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
|
||||||
|
// Part of binary is determined by TableGn.
|
||||||
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
|
|
||||||
|
// Set the conditional execution predicate
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
unsigned OpIdx = 0;
|
||||||
|
|
||||||
|
// Encode Dd / Sd.
|
||||||
|
unsigned RegD = getMachineOpValue(MI, OpIdx++);
|
||||||
|
Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
|
||||||
|
Binary |= (RegD & 0x10) << ARMII::D_BitShift;
|
||||||
|
|
||||||
|
// Encode address base.
|
||||||
|
const MachineOperand &Base = MI.getOperand(OpIdx++);
|
||||||
|
Binary |= getMachineOpValue(MI, Base) << ARMII::RegRnShift;
|
||||||
|
|
||||||
|
// If there is a non-zero immediate offset, encode it.
|
||||||
|
if (Base.isReg()) {
|
||||||
|
const MachineOperand &Offset = MI.getOperand(OpIdx);
|
||||||
|
if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) {
|
||||||
|
if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add)
|
||||||
|
Binary |= 1 << ARMII::U_BitShift;
|
||||||
|
// Immediate offset is multiplied by 4.
|
||||||
|
Binary |= ImmOffs >> 2;
|
||||||
|
emitWordLE(Binary);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If immediate offset is omitted, default to +0.
|
||||||
|
Binary |= 1 << ARMII::U_BitShift;
|
||||||
|
|
||||||
|
emitWordLE(Binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||||
|
// Part of binary is determined by TableGn.
|
||||||
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
|
|
||||||
|
// Set the conditional execution predicate
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
// Set base address operand
|
||||||
|
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
|
||||||
|
|
||||||
|
// Set addressing mode by modifying bits U(23) and P(24)
|
||||||
|
const MachineOperand &MO = MI.getOperand(1);
|
||||||
|
Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm()));
|
||||||
|
|
||||||
|
// Set bit W(21)
|
||||||
|
if (ARM_AM::getAM5WBFlag(MO.getImm()))
|
||||||
|
Binary |= 0x1 << ARMII::W_BitShift;
|
||||||
|
|
||||||
|
// First register is encoded in Dd.
|
||||||
|
unsigned FirstReg = MI.getOperand(4).getReg();
|
||||||
|
Binary |= ARMRegisterInfo::getRegisterNumbering(FirstReg)<< ARMII::RegRdShift;
|
||||||
|
|
||||||
|
// Number of registers are encoded in offset field.
|
||||||
|
unsigned NumRegs = 1;
|
||||||
|
for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
|
||||||
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
|
if (!MO.isReg() || MO.isImplicit())
|
||||||
|
break;
|
||||||
|
++NumRegs;
|
||||||
|
}
|
||||||
|
Binary |= NumRegs * 2;
|
||||||
|
|
||||||
|
emitWordLE(Binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
|
||||||
|
// Part of binary is determined by TableGn.
|
||||||
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
|
|
||||||
|
// Set the conditional execution predicate
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
emitWordLE(Binary);
|
||||||
|
}
|
||||||
|
|
||||||
#include "ARMGenCodeEmitter.inc"
|
#include "ARMGenCodeEmitter.inc"
|
||||||
|
@ -19,29 +19,33 @@ class Format<bits<5> val> {
|
|||||||
bits<5> Value = val;
|
bits<5> Value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
def Pseudo : Format<1>;
|
def Pseudo : Format<1>;
|
||||||
def MulFrm : Format<2>;
|
def MulFrm : Format<2>;
|
||||||
def BrFrm : Format<3>;
|
def BrFrm : Format<3>;
|
||||||
def BrMiscFrm : Format<4>;
|
def BrMiscFrm : Format<4>;
|
||||||
|
|
||||||
def DPFrm : Format<5>;
|
def DPFrm : Format<5>;
|
||||||
def DPSoRegFrm : Format<6>;
|
def DPSoRegFrm : Format<6>;
|
||||||
|
|
||||||
def LdFrm : Format<7>;
|
def LdFrm : Format<7>;
|
||||||
def StFrm : Format<8>;
|
def StFrm : Format<8>;
|
||||||
def LdMiscFrm : Format<9>;
|
def LdMiscFrm : Format<9>;
|
||||||
def StMiscFrm : Format<10>;
|
def StMiscFrm : Format<10>;
|
||||||
def LdMulFrm : Format<11>;
|
def LdMulFrm : Format<11>;
|
||||||
def StMulFrm : Format<12>;
|
def StMulFrm : Format<12>;
|
||||||
|
|
||||||
def ArithMiscFrm: Format<13>;
|
def ArithMiscFrm : Format<13>;
|
||||||
def ExtFrm : Format<14>;
|
def ExtFrm : Format<14>;
|
||||||
def VFPFrm : Format<15>;
|
|
||||||
def VFPUnaryFrm : Format<16>;
|
def VFPUnaryFrm : Format<15>;
|
||||||
def VFPBinaryFrm: Format<17>;
|
def VFPBinaryFrm : Format<16>;
|
||||||
def VFPConv1Frm : Format<18>;
|
def VFPConv1Frm : Format<17>;
|
||||||
def VFPConv2Frm : Format<19>;
|
def VFPConv2Frm : Format<18>;
|
||||||
def ThumbFrm : Format<20>;
|
def VFPLdStFrm : Format<19>;
|
||||||
|
def VFPLdStMulFrm : Format<20>;
|
||||||
|
def VFPMiscFrm : Format<21>;
|
||||||
|
|
||||||
|
def ThumbFrm : Format<22>;
|
||||||
|
|
||||||
// Misc flag for data processing instructions that indicates whether
|
// Misc flag for data processing instructions that indicates whether
|
||||||
// the instruction has a Rn register operand.
|
// the instruction has a Rn register operand.
|
||||||
@ -738,30 +742,45 @@ class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
|
|||||||
// ARM VFP Instruction templates.
|
// ARM VFP Instruction templates.
|
||||||
//
|
//
|
||||||
|
|
||||||
// ARM Float Instruction
|
// ARM VFP addrmode5 loads and stores
|
||||||
class ASI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
|
class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
|
||||||
: AI<oops, iops, VFPFrm, opc, asm, pattern> {
|
string opc, string asm, list<dag> pattern>
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
class ASI5<dag oops, dag iops, string opc, string asm, list<dag> pattern>
|
|
||||||
: I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
: I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
||||||
VFPFrm, opc, asm, "", pattern> {
|
VFPLdStFrm, opc, asm, "", pattern> {
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
// TODO: Mark the instructions with the appropriate subtarget info.
|
||||||
|
let Inst{27-24} = opcod1;
|
||||||
|
let Inst{21-20} = opcod2;
|
||||||
|
let Inst{11-8} = 0b1011;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARM Double Instruction
|
class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
|
||||||
class ADI<dag oops, dag iops, string opc, string asm, list<dag> pattern>
|
string opc, string asm, list<dag> pattern>
|
||||||
: AI<oops, iops, VFPFrm, opc, asm, pattern> {
|
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
class ADI5<dag oops, dag iops, string opc, string asm, list<dag> pattern>
|
|
||||||
: I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
: I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
||||||
VFPFrm, opc, asm, "", pattern> {
|
VFPLdStFrm, opc, asm, "", pattern> {
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
// TODO: Mark the instructions with the appropriate subtarget info.
|
||||||
|
let Inst{27-24} = opcod1;
|
||||||
|
let Inst{21-20} = opcod2;
|
||||||
|
let Inst{11-8} = 0b1010;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load / store multiple
|
||||||
|
class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
|
||||||
|
: XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
||||||
|
VFPLdStMulFrm, asm, "", pattern> {
|
||||||
|
// TODO: Mark the instructions with the appropriate subtarget info.
|
||||||
|
let Inst{27-25} = 0b110;
|
||||||
|
let Inst{11-8} = 0b1011;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
|
||||||
|
: XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
||||||
|
VFPLdStMulFrm, asm, "", pattern> {
|
||||||
|
// TODO: Mark the instructions with the appropriate subtarget info.
|
||||||
|
let Inst{27-25} = 0b110;
|
||||||
|
let Inst{11-8} = 0b1010;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Double precision, unary
|
// Double precision, unary
|
||||||
class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
|
class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
|
||||||
string opc, string asm, list<dag> pattern>
|
string opc, string asm, list<dag> pattern>
|
||||||
@ -817,32 +836,6 @@ class AVConv2I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
|
|||||||
let Inst{6} = 1;
|
let Inst{6} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special cases.
|
|
||||||
class AXSI<dag oops, dag iops, string asm, list<dag> pattern>
|
|
||||||
: XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone,
|
|
||||||
VFPFrm, asm, "", pattern> {
|
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
|
|
||||||
: XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
|
||||||
VFPFrm, asm, "", pattern> {
|
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
class AXDI<dag oops, dag iops, string asm, list<dag> pattern>
|
|
||||||
: XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone,
|
|
||||||
VFPFrm, asm, "", pattern> {
|
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
|
|
||||||
: XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
|
|
||||||
VFPFrm, asm, "", pattern> {
|
|
||||||
// TODO: Mark the instructions with the appropriate subtarget info.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,46 +69,48 @@ namespace ARMII {
|
|||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Instruction encoding formats.
|
// Instruction encoding formats.
|
||||||
//
|
//
|
||||||
FormShift = 10,
|
FormShift = 10,
|
||||||
FormMask = 0x1f << FormShift,
|
FormMask = 0x1f << FormShift,
|
||||||
|
|
||||||
// Pseudo instructions
|
// Pseudo instructions
|
||||||
Pseudo = 1 << FormShift,
|
Pseudo = 1 << FormShift,
|
||||||
|
|
||||||
// Multiply instructions
|
// Multiply instructions
|
||||||
MulFrm = 2 << FormShift,
|
MulFrm = 2 << FormShift,
|
||||||
|
|
||||||
// Branch instructions
|
// Branch instructions
|
||||||
BrFrm = 3 << FormShift,
|
BrFrm = 3 << FormShift,
|
||||||
BrMiscFrm = 4 << FormShift,
|
BrMiscFrm = 4 << FormShift,
|
||||||
|
|
||||||
// Data Processing instructions
|
// Data Processing instructions
|
||||||
DPFrm = 5 << FormShift,
|
DPFrm = 5 << FormShift,
|
||||||
DPSoRegFrm = 6 << FormShift,
|
DPSoRegFrm = 6 << FormShift,
|
||||||
|
|
||||||
// Load and Store
|
// Load and Store
|
||||||
LdFrm = 7 << FormShift,
|
LdFrm = 7 << FormShift,
|
||||||
StFrm = 8 << FormShift,
|
StFrm = 8 << FormShift,
|
||||||
LdMiscFrm = 9 << FormShift,
|
LdMiscFrm = 9 << FormShift,
|
||||||
StMiscFrm = 10 << FormShift,
|
StMiscFrm = 10 << FormShift,
|
||||||
LdMulFrm = 11 << FormShift,
|
LdMulFrm = 11 << FormShift,
|
||||||
StMulFrm = 12 << FormShift,
|
StMulFrm = 12 << FormShift,
|
||||||
|
|
||||||
// Miscellaneous arithmetic instructions
|
// Miscellaneous arithmetic instructions
|
||||||
ArithMiscFrm= 13 << FormShift,
|
ArithMiscFrm = 13 << FormShift,
|
||||||
|
|
||||||
// Extend instructions
|
// Extend instructions
|
||||||
ExtFrm = 14 << FormShift,
|
ExtFrm = 14 << FormShift,
|
||||||
|
|
||||||
// VFP formats
|
// VFP formats
|
||||||
VPFFrm = 15 << FormShift,
|
VFPUnaryFrm = 15 << FormShift,
|
||||||
VFPUnaryFrm = 16 << FormShift,
|
VFPBinaryFrm = 16 << FormShift,
|
||||||
VFPBinaryFrm = 17 << FormShift,
|
VFPConv1Frm = 17 << FormShift,
|
||||||
VFPConv1Frm = 18 << FormShift,
|
VFPConv2Frm = 18 << FormShift,
|
||||||
VFPConv2Frm = 19 << FormShift,
|
VFPLdStFrm = 19 << FormShift,
|
||||||
|
VFPLdStMulFrm = 20 << FormShift,
|
||||||
|
VFPMiscFrm = 21 << FormShift,
|
||||||
|
|
||||||
// Thumb format
|
// Thumb format
|
||||||
ThumbFrm = 20 << FormShift,
|
ThumbFrm = 22 << FormShift,
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Field shifts - such shifts are used to set field while generating
|
// Field shifts - such shifts are used to set field while generating
|
||||||
|
@ -35,20 +35,20 @@ def arm_fmdrr : SDNode<"ARMISD::FMDRR", SDT_FMDRR>;
|
|||||||
//
|
//
|
||||||
|
|
||||||
let isSimpleLoad = 1 in {
|
let isSimpleLoad = 1 in {
|
||||||
def FLDD : ADI5<(outs DPR:$dst), (ins addrmode5:$addr),
|
def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
|
||||||
"fldd", " $dst, $addr",
|
"fldd", " $dst, $addr",
|
||||||
[(set DPR:$dst, (load addrmode5:$addr))]>;
|
[(set DPR:$dst, (load addrmode5:$addr))]>;
|
||||||
|
|
||||||
def FLDS : ASI5<(outs SPR:$dst), (ins addrmode5:$addr),
|
def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
|
||||||
"flds", " $dst, $addr",
|
"flds", " $dst, $addr",
|
||||||
[(set SPR:$dst, (load addrmode5:$addr))]>;
|
[(set SPR:$dst, (load addrmode5:$addr))]>;
|
||||||
} // isSimpleLoad
|
} // isSimpleLoad
|
||||||
|
|
||||||
def FSTD : ADI5<(outs), (ins DPR:$src, addrmode5:$addr),
|
def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
|
||||||
"fstd", " $src, $addr",
|
"fstd", " $src, $addr",
|
||||||
[(store DPR:$src, addrmode5:$addr)]>;
|
[(store DPR:$src, addrmode5:$addr)]>;
|
||||||
|
|
||||||
def FSTS : ASI5<(outs), (ins SPR:$src, addrmode5:$addr),
|
def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
|
||||||
"fsts", " $src, $addr",
|
"fsts", " $src, $addr",
|
||||||
[(store SPR:$src, addrmode5:$addr)]>;
|
[(store SPR:$src, addrmode5:$addr)]>;
|
||||||
|
|
||||||
@ -60,24 +60,32 @@ let mayLoad = 1 in {
|
|||||||
def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
|
def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
|
||||||
variable_ops),
|
variable_ops),
|
||||||
"fldm${addr:submode}d${p} ${addr:base}, $dst1",
|
"fldm${addr:submode}d${p} ${addr:base}, $dst1",
|
||||||
[]>;
|
[]> {
|
||||||
|
let Inst{20} = 1;
|
||||||
|
}
|
||||||
|
|
||||||
def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
|
def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
|
||||||
variable_ops),
|
variable_ops),
|
||||||
"fldm${addr:submode}s${p} ${addr:base}, $dst1",
|
"fldm${addr:submode}s${p} ${addr:base}, $dst1",
|
||||||
[]>;
|
[]> {
|
||||||
|
let Inst{20} = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mayStore = 1 in {
|
let mayStore = 1 in {
|
||||||
def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
|
def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
|
||||||
variable_ops),
|
variable_ops),
|
||||||
"fstm${addr:submode}d${p} ${addr:base}, $src1",
|
"fstm${addr:submode}d${p} ${addr:base}, $src1",
|
||||||
[]>;
|
[]> {
|
||||||
|
let Inst{20} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
|
def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
|
||||||
variable_ops),
|
variable_ops),
|
||||||
"fstm${addr:submode}s${p} ${addr:base}, $src1",
|
"fstm${addr:submode}s${p} ${addr:base}, $src1",
|
||||||
[]>;
|
[]> {
|
||||||
|
let Inst{20} = 0;
|
||||||
|
}
|
||||||
} // mayStore
|
} // mayStore
|
||||||
|
|
||||||
// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
|
// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
|
||||||
@ -384,4 +392,11 @@ def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100,
|
|||||||
//
|
//
|
||||||
|
|
||||||
let Defs = [CPSR] in
|
let Defs = [CPSR] in
|
||||||
def FMSTAT : ASI<(outs), (ins), "fmstat", "", [(arm_fmstat)]>;
|
def FMSTAT : AI<(outs), (ins), VFPMiscFrm, "fmstat", "", [(arm_fmstat)]> {
|
||||||
|
let Inst{27-20} = 0b11101111;
|
||||||
|
let Inst{19-16} = 0b0001;
|
||||||
|
let Inst{15-12} = 0b1111;
|
||||||
|
let Inst{11-8} = 0b1010;
|
||||||
|
let Inst{7} = 0;
|
||||||
|
let Inst{4} = 1;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user