mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Encode extend instructions; more clean up.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58818 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e187726208
commit
97f48c39fd
@ -98,6 +98,8 @@ namespace {
|
||||
|
||||
void emitMulFrmInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitExtendInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitBranchInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitMiscBranchInstruction(const MachineInstr &MI);
|
||||
@ -282,6 +284,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
case ARMII::MulFrm:
|
||||
emitMulFrmInstruction(MI);
|
||||
break;
|
||||
case ARMII::ExtFrm:
|
||||
emitExtendInstruction(MI);
|
||||
break;
|
||||
case ARMII::BrFrm:
|
||||
emitBranchInstruction(MI);
|
||||
break;
|
||||
@ -349,7 +354,7 @@ void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
||||
unsigned Binary = 0xd << 21; // mov: Insts{24-21} = 0b1101
|
||||
|
||||
// Set the conditional execution predicate.
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Encode Rd.
|
||||
Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
|
||||
@ -364,7 +369,7 @@ void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
||||
Binary = 0xc << 21; // orr: Insts{24-21} = 0b1100
|
||||
|
||||
// Set the conditional execution predicate.
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Encode Rd.
|
||||
Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
|
||||
@ -488,7 +493,9 @@ unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
|
||||
|
||||
unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
|
||||
// Encode rotate_imm.
|
||||
unsigned Binary = (ARM_AM::getSOImmValRot(SoImm) >> 1) << ARMII::RotImmShift;
|
||||
unsigned Binary = (ARM_AM::getSOImmValRot(SoImm) >> 1)
|
||||
<< ARMII::SoRotImmShift;
|
||||
|
||||
// Encode immed_8.
|
||||
Binary |= ARM_AM::getSOImmValImm(SoImm);
|
||||
return Binary;
|
||||
@ -512,7 +519,7 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Encode S bit if MI modifies CPSR.
|
||||
Binary |= getAddrModeSBit(MI, TID);
|
||||
@ -570,7 +577,7 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Set first operand
|
||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
|
||||
@ -623,7 +630,7 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Set first operand
|
||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
|
||||
@ -656,7 +663,7 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
|
||||
}
|
||||
|
||||
// This instr is in immediate offset/index encoding, set bit 22 to 1.
|
||||
Binary |= 1 << 22;
|
||||
Binary |= 1 << ARMII::AM3_I_BitShift;
|
||||
if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) {
|
||||
// Set operands
|
||||
Binary |= (ImmOffs >> 4) << 8; // immedH
|
||||
@ -671,7 +678,7 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Set first operand
|
||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
|
||||
@ -686,14 +693,14 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||
switch (Mode) {
|
||||
default: assert(0 && "Unknown addressing sub-mode!");
|
||||
case ARM_AM::da: break;
|
||||
case ARM_AM::db: Binary |= 0x1 << 24; break;
|
||||
case ARM_AM::ia: Binary |= 0x1 << 23; break;
|
||||
case ARM_AM::ib: Binary |= 0x3 << 23; break;
|
||||
case ARM_AM::db: Binary |= 0x1 << ARMII::P_BitShift; break;
|
||||
case ARM_AM::ia: Binary |= 0x1 << ARMII::U_BitShift; break;
|
||||
case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
|
||||
}
|
||||
|
||||
// Set bit W(21)
|
||||
if (ARM_AM::getAM4WBFlag(MO.getImm()))
|
||||
Binary |= 0x1 << 21;
|
||||
Binary |= 0x1 << ARMII::W_BitShift;
|
||||
|
||||
// Set registers
|
||||
for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) {
|
||||
@ -716,14 +723,14 @@ void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Encode S bit if MI modifies CPSR.
|
||||
Binary |= getAddrModeSBit(MI, TID);
|
||||
|
||||
// 32x32->64bit operations have two destination registers. The number
|
||||
// of register definitions will tell us if that's what we're dealing with.
|
||||
int OpIdx = 0;
|
||||
unsigned OpIdx = 0;
|
||||
if (TID.getNumDefs() == 2)
|
||||
Binary |= getMachineOpValue (MI, OpIdx++) << ARMII::RegRdLoShift;
|
||||
|
||||
@ -738,8 +745,47 @@ void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
|
||||
|
||||
// Many multiple instructions (e.g. MLA) have three src operands. Encode
|
||||
// it as Rn (for multiply, that's in the same offset as RdLo.
|
||||
if (TID.getNumOperands() - TID.getNumDefs() == 3)
|
||||
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdLoShift;
|
||||
if (TID.getNumOperands() > OpIdx &&
|
||||
!TID.OpInfo[OpIdx].isPredicate() &&
|
||||
!TID.OpInfo[OpIdx].isOptionalDef())
|
||||
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdLoShift;
|
||||
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
// 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 Rd
|
||||
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
|
||||
|
||||
const MachineOperand &MO1 = MI.getOperand(OpIdx++);
|
||||
const MachineOperand &MO2 = MI.getOperand(OpIdx);
|
||||
if (MO2.isReg()) {
|
||||
// Two register operand form.
|
||||
// Encode Rn.
|
||||
Binary |= getMachineOpValue(MI, MO1) << ARMII::RegRnShift;
|
||||
|
||||
// Encode Rm.
|
||||
Binary |= getMachineOpValue(MI, MO2);
|
||||
++OpIdx;
|
||||
} else {
|
||||
Binary |= getMachineOpValue(MI, MO1);
|
||||
}
|
||||
|
||||
// Encode rot imm (0, 8, 16, or 24) if it has a rotate immediate operand.
|
||||
if (MI.getOperand(OpIdx).isImm() &&
|
||||
!TID.OpInfo[OpIdx].isPredicate() &&
|
||||
!TID.OpInfo[OpIdx].isOptionalDef())
|
||||
Binary |= (getMachineOpValue(MI, OpIdx) / 8) << ARMII::ExtRotImmShift;
|
||||
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
@ -754,17 +800,11 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
// Set signed_immed_24 field
|
||||
Binary |= getMachineOpValue(MI, 0);
|
||||
|
||||
// if it is a conditional branch, set cond field
|
||||
if (TID.Opcode == ARM::Bcc) {
|
||||
Binary &= 0x0FFFFFFF; // clear conditional field
|
||||
Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field
|
||||
}
|
||||
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
@ -780,7 +820,7 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
// Set the conditional execution predicate
|
||||
Binary |= II->getPredicate(&MI) << 28;
|
||||
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||
|
||||
if (TID.Opcode == ARM::BX_RET)
|
||||
// The return register is LR.
|
||||
|
@ -34,9 +34,10 @@ def StMiscFrm : Format<10>;
|
||||
def LdMulFrm : Format<11>;
|
||||
def StMulFrm : Format<12>;
|
||||
|
||||
def ArithMisc : Format<13>;
|
||||
def ThumbFrm : Format<14>;
|
||||
def VFPFrm : Format<15>;
|
||||
def ArithMiscFrm: Format<13>;
|
||||
def ExtFrm : Format<14>;
|
||||
def ThumbFrm : Format<15>;
|
||||
def VFPFrm : Format<16>;
|
||||
|
||||
// Misc flag for data processing instructions that indicates whether
|
||||
// the instruction has a Rn register operand.
|
||||
@ -123,11 +124,11 @@ class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
|
||||
class AI<dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm,"",pattern>;
|
||||
asm, "", pattern>;
|
||||
class AsI<dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm,"",pattern>;
|
||||
asm, "", pattern>;
|
||||
class AXI<dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
|
||||
@ -137,7 +138,7 @@ class AXI<dag oops, dag iops, Format f, string asm,
|
||||
class ABI<bits<4> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
|
||||
asm,"",pattern> {
|
||||
asm, "", pattern> {
|
||||
let Inst{27-24} = opcod;
|
||||
}
|
||||
class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
|
||||
@ -645,7 +646,7 @@ class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
|
||||
class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
|
||||
asm,"",pattern> {
|
||||
asm, "", pattern> {
|
||||
let Inst{7-4} = 0b1001;
|
||||
let Inst{20} = 0; // S bit
|
||||
let Inst{27-21} = opcod;
|
||||
@ -653,7 +654,7 @@ class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
|
||||
asm,"",pattern> {
|
||||
asm, "", pattern> {
|
||||
let Inst{7-4} = 0b1001;
|
||||
let Inst{27-21} = opcod;
|
||||
}
|
||||
@ -662,7 +663,7 @@ class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
|
||||
asm,"",pattern> {
|
||||
asm, "", pattern> {
|
||||
let Inst{7-4} = 0b1001;
|
||||
let Inst{20} = 1;
|
||||
let Inst{27-21} = opcod;
|
||||
@ -672,13 +673,22 @@ class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
|
||||
asm,"",pattern> {
|
||||
asm, "", pattern> {
|
||||
let Inst{4} = 0;
|
||||
let Inst{7} = 1;
|
||||
let Inst{20} = 0;
|
||||
let Inst{27-21} = opcod;
|
||||
}
|
||||
|
||||
// Extend instructions.
|
||||
class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{7-4} = 0b0111;
|
||||
let Inst{27-20} = opcod;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
|
||||
|
@ -95,28 +95,34 @@ namespace ARMII {
|
||||
StMulFrm = 12 << FormShift,
|
||||
|
||||
// Miscellaneous arithmetic instructions
|
||||
ArithMisc = 13 << FormShift,
|
||||
ArithMiscFrm= 13 << FormShift,
|
||||
|
||||
// Extend instructions
|
||||
ExtFrm = 14 << FormShift,
|
||||
|
||||
// Thumb format
|
||||
ThumbFrm = 14 << FormShift,
|
||||
ThumbFrm = 15 << FormShift,
|
||||
|
||||
// VFP format
|
||||
VPFFrm = 15 << FormShift,
|
||||
VPFFrm = 16 << FormShift,
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Field shifts - such shifts are used to set field while generating
|
||||
// machine instructions.
|
||||
RotImmShift = 8,
|
||||
RegRsShift = 8,
|
||||
RegRdLoShift = 12,
|
||||
RegRdShift = 12,
|
||||
RegRdHiShift = 16,
|
||||
RegRnShift = 16,
|
||||
L_BitShift = 20,
|
||||
S_BitShift = 20,
|
||||
U_BitShift = 23,
|
||||
IndexShift = 24,
|
||||
I_BitShift = 25
|
||||
SoRotImmShift = 8,
|
||||
RegRsShift = 8,
|
||||
ExtRotImmShift = 10,
|
||||
RegRdLoShift = 12,
|
||||
RegRdShift = 12,
|
||||
RegRdHiShift = 16,
|
||||
RegRnShift = 16,
|
||||
S_BitShift = 20,
|
||||
W_BitShift = 21,
|
||||
AM3_I_BitShift = 22,
|
||||
U_BitShift = 23,
|
||||
P_BitShift = 24,
|
||||
I_BitShift = 25,
|
||||
CondShift = 28
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -390,25 +390,31 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
|
||||
|
||||
/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
|
||||
/// register and one whose operand is a register rotated by 8/16/24.
|
||||
multiclass AI_unary_rrot<string opc, PatFrag opnode> {
|
||||
def r : AI<(outs GPR:$dst), (ins GPR:$Src), Pseudo,
|
||||
/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
|
||||
multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
|
||||
def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src),
|
||||
opc, " $dst, $Src",
|
||||
[(set GPR:$dst, (opnode GPR:$Src))]>, Requires<[IsARM, HasV6]>;
|
||||
def r_rot : AI<(outs GPR:$dst), (ins GPR:$Src, i32imm:$rot), Pseudo,
|
||||
[(set GPR:$dst, (opnode GPR:$Src))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
|
||||
opc, " $dst, $Src, ror $rot",
|
||||
[(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
}
|
||||
|
||||
/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
|
||||
/// register and one whose operand is a register rotated by 8/16/24.
|
||||
multiclass AI_bin_rrot<string opc, PatFrag opnode> {
|
||||
def rr : AI<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
|
||||
Pseudo, opc, " $dst, $LHS, $RHS",
|
||||
multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
|
||||
def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
|
||||
opc, " $dst, $LHS, $RHS",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
def rr_rot : AI<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
|
||||
Pseudo, opc, " $dst, $LHS, $RHS, ror $rot",
|
||||
def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
|
||||
opc, " $dst, $LHS, $RHS, ror $rot",
|
||||
[(set GPR:$dst, (opnode GPR:$LHS,
|
||||
(rotr GPR:$RHS, rot_imm:$rot)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
@ -781,31 +787,36 @@ def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
|
||||
|
||||
// Sign extenders
|
||||
|
||||
defm SXTB : AI_unary_rrot<"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
|
||||
defm SXTH : AI_unary_rrot<"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
|
||||
defm SXTB : AI_unary_rrot<0b01101010,
|
||||
"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
|
||||
defm SXTH : AI_unary_rrot<0b01101011,
|
||||
"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
|
||||
|
||||
defm SXTAB : AI_bin_rrot<"sxtab",
|
||||
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
|
||||
defm SXTAH : AI_bin_rrot<"sxtah",
|
||||
BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
|
||||
defm SXTAB : AI_bin_rrot<0b01101010,
|
||||
"sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
|
||||
defm SXTAH : AI_bin_rrot<0b01101011,
|
||||
"sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
|
||||
|
||||
// TODO: SXT(A){B|H}16
|
||||
|
||||
// Zero extenders
|
||||
|
||||
let AddedComplexity = 16 in {
|
||||
defm UXTB : AI_unary_rrot<"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
|
||||
defm UXTH : AI_unary_rrot<"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
|
||||
defm UXTB16 : AI_unary_rrot<"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
|
||||
defm UXTB : AI_unary_rrot<0b01101110,
|
||||
"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
|
||||
defm UXTH : AI_unary_rrot<0b01101111,
|
||||
"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
|
||||
defm UXTB16 : AI_unary_rrot<0b01101100,
|
||||
"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
|
||||
|
||||
def : ARMV6Pat<(and (shl GPR:$Src, 8), 0xFF00FF),
|
||||
(UXTB16r_rot GPR:$Src, 24)>;
|
||||
def : ARMV6Pat<(and (srl GPR:$Src, 8), 0xFF00FF),
|
||||
(UXTB16r_rot GPR:$Src, 8)>;
|
||||
|
||||
defm UXTAB : AI_bin_rrot<"uxtab",
|
||||
defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
|
||||
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
|
||||
defm UXTAH : AI_bin_rrot<"uxtah",
|
||||
defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
|
||||
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
|
||||
}
|
||||
|
||||
@ -1090,15 +1101,15 @@ defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||
// Misc. Arithmetic Instructions.
|
||||
//
|
||||
|
||||
def CLZ : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
def CLZ : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
"clz", " $dst, $src",
|
||||
[(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]>;
|
||||
|
||||
def REV : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
def REV : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
"rev", " $dst, $src",
|
||||
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]>;
|
||||
|
||||
def REV16 : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
def REV16 : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
"rev16", " $dst, $src",
|
||||
[(set GPR:$dst,
|
||||
(or (and (srl GPR:$src, 8), 0xFF),
|
||||
@ -1107,7 +1118,7 @@ def REV16 : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
(and (shl GPR:$src, 8), 0xFF000000)))))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
def REVSH : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
def REVSH : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
"revsh", " $dst, $src",
|
||||
[(set GPR:$dst,
|
||||
(sext_inreg
|
||||
@ -1116,7 +1127,7 @@ def REVSH : AI<(outs GPR:$dst), (ins GPR:$src), ArithMisc,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
def PKHBT : AI<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
Pseudo, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
|
||||
ArithMiscFrm, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
|
||||
(and (shl GPR:$src2, (i32 imm:$shamt)),
|
||||
0xFFFF0000)))]>,
|
||||
@ -1130,7 +1141,7 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
|
||||
|
||||
|
||||
def PKHTB : AI<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
Pseudo, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
|
||||
ArithMiscFrm, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
|
||||
(and (sra GPR:$src2, imm16_31:$shamt),
|
||||
0xFFFF)))]>, Requires<[IsARM, HasV6]>;
|
||||
|
Loading…
Reference in New Issue
Block a user