mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
ARM mode encoding information for CLZ, RBIT, REV*, and PKH*.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117165 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
abf4b382a6
commit
f8da5f5dfa
@ -988,11 +988,36 @@ class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
|
||||
}
|
||||
|
||||
// Misc Arithmetic instructions.
|
||||
class AMiscA1I<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
|
||||
InstrItinClass itin, string opc, string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin,
|
||||
opc, asm, "", pattern> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rm;
|
||||
let Inst{27-20} = opcod;
|
||||
let Inst{19-16} = 0b1111;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{7-4} = opc7_4;
|
||||
let Inst{3-0} = Rm;
|
||||
}
|
||||
|
||||
// PKH instructions
|
||||
class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin,
|
||||
opc, asm, "", pattern> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rn;
|
||||
bits<4> Rm;
|
||||
bits<8> sh;
|
||||
let Inst{27-20} = opcod;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-7} = sh{7-3};
|
||||
let Inst{6} = tb;
|
||||
let Inst{5-4} = 0b01;
|
||||
let Inst{3-0} = Rm;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -2557,55 +2557,35 @@ defm SMUS : AI_sdml<1, "smus">;
|
||||
// Misc. Arithmetic Instructions.
|
||||
//
|
||||
|
||||
def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
"clz", "\t$dst, $src",
|
||||
[(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 CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iUNAr, "clz", "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>;
|
||||
|
||||
def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
"rbit", "\t$dst, $src",
|
||||
[(set GPR:$dst, (ARMrbit GPR:$src))]>,
|
||||
Requires<[IsARM, HasV6T2]> {
|
||||
let Inst{7-4} = 0b0011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iUNAr, "rbit", "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd, (ARMrbit GPR:$Rm))]>,
|
||||
Requires<[IsARM, HasV6T2]>;
|
||||
|
||||
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
"rev", "\t$dst, $src",
|
||||
[(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 REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iUNAr, "rev", "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>;
|
||||
|
||||
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
"rev16", "\t$dst, $src",
|
||||
[(set GPR:$dst,
|
||||
(or (and (srl GPR:$src, (i32 8)), 0xFF),
|
||||
(or (and (shl GPR:$src, (i32 8)), 0xFF00),
|
||||
(or (and (srl GPR:$src, (i32 8)), 0xFF0000),
|
||||
(and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{7-4} = 0b1011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iUNAr, "rev16", "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd,
|
||||
(or (and (srl GPR:$Rm, (i32 8)), 0xFF),
|
||||
(or (and (shl GPR:$Rm, (i32 8)), 0xFF00),
|
||||
(or (and (srl GPR:$Rm, (i32 8)), 0xFF0000),
|
||||
(and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
|
||||
"revsh", "\t$dst, $src",
|
||||
[(set GPR:$dst,
|
||||
def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm),
|
||||
IIC_iUNAr, "revsh", "\t$Rd, $Rm",
|
||||
[(set GPR:$Rd,
|
||||
(sext_inreg
|
||||
(or (srl (and GPR:$src, 0xFF00), (i32 8)),
|
||||
(shl GPR:$src, (i32 8))), i16))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{7-4} = 0b1011;
|
||||
let Inst{11-8} = 0b1111;
|
||||
let Inst{19-16} = 0b1111;
|
||||
}
|
||||
(or (srl (and GPR:$Rm, 0xFF00), (i32 8)),
|
||||
(shl GPR:$Rm, (i32 8))), i16))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
def lsl_shift_imm : SDNodeXForm<imm, [{
|
||||
unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
|
||||
@ -2616,21 +2596,19 @@ def lsl_amt : PatLeaf<(i32 imm), [{
|
||||
return (N->getZExtValue() < 32);
|
||||
}], lsl_shift_imm>;
|
||||
|
||||
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
|
||||
(ins GPR:$src1, GPR:$src2, shift_imm:$sh),
|
||||
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
|
||||
(and (shl GPR:$src2, lsl_amt:$sh),
|
||||
0xFFFF0000)))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{6-4} = 0b001;
|
||||
}
|
||||
def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
|
||||
(ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
|
||||
IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
|
||||
[(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
|
||||
(and (shl GPR:$Rm, lsl_amt:$sh),
|
||||
0xFFFF0000)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
// Alternate cases for PKHBT where identities eliminate some nodes.
|
||||
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
|
||||
(PKHBT GPR:$src1, GPR:$src2, 0)>;
|
||||
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
|
||||
(PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
|
||||
def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
|
||||
(PKHBT GPR:$Rn, GPR:$Rm, 0)>;
|
||||
def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
|
||||
(PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>;
|
||||
|
||||
def asr_shift_imm : SDNodeXForm<imm, [{
|
||||
unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
|
||||
@ -2643,15 +2621,13 @@ def asr_amt : PatLeaf<(i32 imm), [{
|
||||
|
||||
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
|
||||
// will match the pattern below.
|
||||
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
|
||||
(ins GPR:$src1, GPR:$src2, shift_imm:$sh),
|
||||
IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
|
||||
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
|
||||
(and (sra GPR:$src2, asr_amt:$sh),
|
||||
0xFFFF)))]>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
let Inst{6-4} = 0b101;
|
||||
}
|
||||
def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
|
||||
(ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
|
||||
IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
|
||||
[(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
|
||||
(and (sra GPR:$Rm, asr_amt:$sh),
|
||||
0xFFFF)))]>,
|
||||
Requires<[IsARM, HasV6]>;
|
||||
|
||||
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
|
||||
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
|
||||
|
@ -7,6 +7,9 @@
|
||||
; compiler never generates, so we need the integrated assembler to be
|
||||
; able to test those at all.
|
||||
|
||||
declare void @llvm.trap() nounwind
|
||||
declare i32 @llvm.ctlz.i32(i32)
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
; CHECK: foo
|
||||
@ -182,4 +185,56 @@ define i32 @f18(i32 %a, i16 %x, i32 %y) {
|
||||
ret i32 %tmp5
|
||||
}
|
||||
|
||||
declare void @llvm.trap() nounwind
|
||||
define i32 @f19(i32 %x) {
|
||||
; CHECK: f19
|
||||
; CHECK: clz r0, r0 @ encoding: [0x10,0x0f,0x6f,0xe1]
|
||||
%tmp.1 = call i32 @llvm.ctlz.i32( i32 %x )
|
||||
ret i32 %tmp.1
|
||||
}
|
||||
|
||||
define i32 @f20(i32 %X) {
|
||||
; CHECK: f20
|
||||
; CHECK: rev16 r0, r0 @ encoding: [0xb0,0x0f,0xbf,0xe6]
|
||||
%tmp1 = lshr i32 %X, 8
|
||||
%X15 = bitcast i32 %X to i32
|
||||
%tmp4 = shl i32 %X15, 8
|
||||
%tmp2 = and i32 %tmp1, 16711680
|
||||
%tmp5 = and i32 %tmp4, -16777216
|
||||
%tmp9 = and i32 %tmp1, 255
|
||||
%tmp13 = and i32 %tmp4, 65280
|
||||
%tmp6 = or i32 %tmp5, %tmp2
|
||||
%tmp10 = or i32 %tmp6, %tmp13
|
||||
%tmp14 = or i32 %tmp10, %tmp9
|
||||
ret i32 %tmp14
|
||||
}
|
||||
|
||||
define i32 @f21(i32 %X) {
|
||||
; CHECK: f21
|
||||
; CHECK: revsh r0, r0 @ encoding: [0xb0,0x0f,0xff,0xe6]
|
||||
%tmp1 = lshr i32 %X, 8
|
||||
%tmp1.upgrd.1 = trunc i32 %tmp1 to i16
|
||||
%tmp3 = trunc i32 %X to i16
|
||||
%tmp2 = and i16 %tmp1.upgrd.1, 255
|
||||
%tmp4 = shl i16 %tmp3, 8
|
||||
%tmp5 = or i16 %tmp2, %tmp4
|
||||
%tmp5.upgrd.2 = sext i16 %tmp5 to i32
|
||||
ret i32 %tmp5.upgrd.2
|
||||
}
|
||||
|
||||
define i32 @f22(i32 %X, i32 %Y) {
|
||||
; CHECK: f22
|
||||
; CHECK: pkhtb r0, r0, r1, asr #22 @ encoding: [0x51,0x0b,0x80,0xe6]
|
||||
%tmp1 = and i32 %X, -65536
|
||||
%tmp3 = lshr i32 %Y, 22
|
||||
%tmp57 = or i32 %tmp3, %tmp1
|
||||
ret i32 %tmp57
|
||||
}
|
||||
|
||||
define i32 @f23(i32 %X, i32 %Y) {
|
||||
; CHECK: f23
|
||||
; CHECK: pkhbt r0, r0, r1, lsl #18 @ encoding: [0x11,0x09,0x80,0xe6]
|
||||
%tmp19 = and i32 %X, 65535
|
||||
%tmp37 = shl i32 %Y, 18
|
||||
%tmp5 = or i32 %tmp37, %tmp19
|
||||
ret i32 %tmp5
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user