mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-01 16:40:15 +00:00
Encode misc arithmetic instructions.
llvm-svn: 58828
This commit is contained in:
parent
64f40545b3
commit
88726d85eb
@ -100,6 +100,8 @@ namespace {
|
||||
|
||||
void emitExtendInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitMiscArithInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitBranchInstruction(const MachineInstr &MI);
|
||||
|
||||
void emitMiscBranchInstruction(const MachineInstr &MI);
|
||||
@ -287,6 +289,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
case ARMII::ExtFrm:
|
||||
emitExtendInstruction(MI);
|
||||
break;
|
||||
case ARMII::ArithMiscFrm:
|
||||
emitMiscArithInstruction(MI);
|
||||
break;
|
||||
case ARMII::BrFrm:
|
||||
emitBranchInstruction(MI);
|
||||
break;
|
||||
@ -790,6 +795,44 @@ void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitMiscArithInstruction(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 &MO = MI.getOperand(OpIdx++);
|
||||
if (OpIdx == TID.getNumOperands() ||
|
||||
TID.OpInfo[OpIdx].isPredicate() ||
|
||||
TID.OpInfo[OpIdx].isOptionalDef()) {
|
||||
// Encode Rm and it's done.
|
||||
Binary |= getMachineOpValue(MI, MO);
|
||||
emitWordLE(Binary);
|
||||
return;
|
||||
}
|
||||
|
||||
// Encode Rn.
|
||||
Binary |= getMachineOpValue(MI, MO) << ARMII::RegRnShift;
|
||||
|
||||
// Encode Rm.
|
||||
Binary |= getMachineOpValue(MI, OpIdx++);
|
||||
|
||||
// Encode shift_imm.
|
||||
unsigned ShiftAmt = MI.getOperand(OpIdx).getImm();
|
||||
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
|
||||
Binary |= ShiftAmt << ARMII::ShiftShift;
|
||||
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
|
@ -689,6 +689,14 @@ class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
|
||||
let Inst{27-20} = opcod;
|
||||
}
|
||||
|
||||
// Misc Arithmetic instructions.
|
||||
class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{27-20} = opcod;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
|
||||
|
@ -109,6 +109,7 @@ namespace ARMII {
|
||||
//===------------------------------------------------------------------===//
|
||||
// Field shifts - such shifts are used to set field while generating
|
||||
// machine instructions.
|
||||
ShiftShift = 7,
|
||||
SoRotImmShift = 8,
|
||||
RegRsShift = 8,
|
||||
ExtRotImmShift = 10,
|
||||
|
@ -1101,37 +1101,56 @@ defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||
// Misc. Arithmetic Instructions.
|
||||
//
|
||||
|
||||
def CLZ : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
|
||||
"clz", " $dst, $src",
|
||||
[(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]>;
|
||||
[(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
|
||||
let Inst{7-4} = 0b0001;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
|
||||
def REV : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
|
||||
"rev", " $dst, $src",
|
||||
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]>;
|
||||
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
|
||||
let Inst{7-4} = 0b0011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
|
||||
def REV16 : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
|
||||
"rev16", " $dst, $src",
|
||||
[(set GPR:$dst,
|
||||
(or (and (srl GPR:$src, 8), 0xFF),
|
||||
(or (and (shl GPR:$src, 8), 0xFF00),
|
||||
(or (and (srl GPR:$src, 8), 0xFF0000),
|
||||
(and (shl GPR:$src, 8), 0xFF000000)))))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{7-4} = 0b1011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
|
||||
def REVSH : AI<(outs GPR:$dst), (ins GPR:$src), ArithMiscFrm,
|
||||
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
|
||||
"revsh", " $dst, $src",
|
||||
[(set GPR:$dst,
|
||||
(sext_inreg
|
||||
(or (srl (and GPR:$src, 0xFF00), 8),
|
||||
(shl GPR:$src, 8)), i16))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{7-4} = 0b1011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
|
||||
def PKHBT : AI<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
ArithMiscFrm, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
|
||||
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
|
||||
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
"pkhbt", " $dst, $src1, $src2, LSL $shamt",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
|
||||
(and (shl GPR:$src2, (i32 imm:$shamt)),
|
||||
0xFFFF0000)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{6-4} = 0b001;
|
||||
}
|
||||
|
||||
// Alternate cases for PKHBT where identities eliminate some nodes.
|
||||
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
|
||||
@ -1140,11 +1159,14 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
|
||||
(PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
|
||||
|
||||
|
||||
def PKHTB : AI<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
ArithMiscFrm, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
|
||||
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
|
||||
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
|
||||
"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]>;
|
||||
0xFFFF)))]>, Requires<[IsARM, HasV6]> {
|
||||
let Inst{6-4} = 0b101;
|
||||
}
|
||||
|
||||
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
|
||||
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
|
||||
|
Loading…
Reference in New Issue
Block a user