Newer
Older
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
Raul Herbster
committed
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
[(set GPR:$dst, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
(sra GPR:$b, (i32 16))), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
Raul Herbster
committed
multiclass AI_smla<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc,
(opnode (sext_inreg GPR:$a, i16),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
Raul Herbster
committed
def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
Raul Herbster
committed
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sra GPR:$b, (i32 16))), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
// Helper class for AI_smld -- for disassembly only
class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,
InstrItinClass itin, string opc, string asm>
: AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> {
let Inst{4} = 1;
let Inst{5} = swap;
let Inst{6} = sub;
let Inst{7} = 0;
let Inst{21-20} = 0b00;
let Inst{22} = long;
let Inst{27-23} = 0b01110;
}
multiclass AI_smld<bit sub, string opc> {
def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b, $acc">;
def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b, $acc">;
def LD : AMulDualI<1, sub, 0, (outs GPR:$ldst,GPR:$hdst), (ins GPR:$a,GPR:$b),
NoItinerary, !strconcat(opc, "ld"), "\t$ldst, $hdst, $a, $b">;
def LDX : AMulDualI<1, sub, 1, (outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
NoItinerary, !strconcat(opc, "ldx"),"\t$ldst, $hdst, $a, $b">;
}
defm SMLA : AI_smld<0, "smla">;
defm SMLS : AI_smld<1, "smls">;
Johnny Chen
committed
multiclass AI_sdml<bit sub, string opc> {
def D : AMulDualI<0, sub, 0, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
NoItinerary, !strconcat(opc, "d"), "\t$dst, $a, $b"> {
let Inst{15-12} = 0b1111;
}
def DX : AMulDualI<0, sub, 1, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
NoItinerary, !strconcat(opc, "dx"), "\t$dst, $a, $b"> {
let Inst{15-12} = 0b1111;
}
}
defm SMUA : AI_sdml<0, "smua">;
defm SMUS : AI_sdml<1, "smus">;
//===----------------------------------------------------------------------===//
// Misc. Arithmetic Instructions.
//
def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"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 RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"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 REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"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 REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"rev16", "\t$dst, $src",
(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 REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"revsh", "\t$dst, $src",
(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;
}
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
(and (shl GPR:$src2, (i32 imm:$shamt)),
0xFFFF0000)))]>,
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)),
(PKHBT GPR:$src1, GPR:$src2, 0)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
(PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
(and (sra GPR:$src2, imm16_31:$shamt),
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.
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
(PKHTB GPR:$src1, GPR:$src2, 16)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
(PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
//===----------------------------------------------------------------------===//
// Comparison Instructions...
//
Jim Grosbach
committed
defm CMP : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
// Compare-to-zero still works out, just not the relationals
//defm CMN : AI1_cmp_irs<0b1011, "cmn",
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Cheng
committed
defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwin
committed
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Cheng
committed
defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwin
committed
BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Lauro Ramos Venancio
committed
David Goodwin
committed
defm CMPz : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
defm CMNz : AI1_cmp_irs<0b1011, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
// (CMNri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio
committed
David Goodwin
committed
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
(CMNzri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio
committed
Evan Cheng
committed
// Pseudo i64 compares for some floating point compares.
let usesCustomInserter = 1, isBranch = 1, isTerminator = 1,
Defs = [CPSR] in {
def BCCi64 : PseudoInst<(outs),
(ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst),
IIC_Br,
"${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, imm:$cc",
[(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>;
def BCCZi64 : PseudoInst<(outs),
(ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst),
IIC_Br,
"${:comment} B\t$dst GPR:$lhs1, GPR:$lhs2, 0, 0, imm:$cc",
[(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>;
} // usesCustomInserter
// FIXME: should be able to write a pattern for ARMcmov, but can't use
// a two-value operand where a dag node expects two operands. :(
let neverHasSideEffects = 1 in {
Evan Cheng
committed
def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Cheng
committed
IIC_iCMOVr, "mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">, UnaryDP {
Johnny Chen
committed
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
}
Evan Cheng
committed
def MOVCCs : AI1<0b1101, (outs GPR:$dst),
(ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
Evan Cheng
committed
"mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">, UnaryDP {
let Inst{25} = 0;
}
Evan Cheng
committed
def MOVCCi : AI1<0b1101, (outs GPR:$dst),
(ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
Evan Cheng
committed
"mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng
committed
RegConstraint<"$false = $dst">, UnaryDP {
let Inst{25} = 1;
Evan Cheng
committed
}
} // neverHasSideEffects
Jim Grosbach
committed
//===----------------------------------------------------------------------===//
// Atomic operations intrinsics
//
// memory barriers protect the atomic sequences
let hasSideEffects = 1 in {
def DMBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dmb", "",
[(ARMMemBarrier)]>, Requires<[IsARM, HasDB]> {
let Inst{31-4} = 0xf57ff05;
// FIXME: add support for options other than a full system DMB
// See DMB disassembly-only variants below.
Jim Grosbach
committed
def DSBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "dsb", "",
[(ARMSyncBarrier)]>, Requires<[IsARM, HasDB]> {
let Inst{31-4} = 0xf57ff04;
// FIXME: add support for options other than a full system DSB
// See DSB disassembly-only variants below.
def DMB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
"mcr", "\tp15, 0, $zero, c7, c10, 5",
[(ARMMemBarrierMCR GPR:$zero)]>,
Requires<[IsARM, HasV6]> {
// FIXME: add support for options other than a full system DMB
// FIXME: add encoding
}
def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
[(ARMSyncBarrierMCR GPR:$zero)]>,
Requires<[IsARM, HasV6]> {
// FIXME: add support for options other than a full system DSB
// FIXME: add encoding
}
Jim Grosbach
committed
}
Johnny Chen
committed
// Memory Barrier Operations Variants -- for disassembly only
Johnny Chen
committed
def memb_opt : Operand<i32> {
let PrintMethod = "printMemBOption";
}
Johnny Chen
committed
class AMBI<bits<4> op7_4, string opc>
: AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasDB]> {
let Inst{31-8} = 0xf57ff0;
let Inst{7-4} = op7_4;
}
// These DMB variants are for disassembly only.
Johnny Chen
committed
def DMBvar : AMBI<0b0101, "dmb">;
// These DSB variants are for disassembly only.
Johnny Chen
committed
def DSBvar : AMBI<0b0100, "dsb">;
// ISB has only full system option -- for disassembly only
Johnny Chen
committed
def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
Requires<[IsARM, HasDB]> {
let Inst{31-4} = 0xf57ff06;
let Inst{3-0} = 0b1111;
}
Jim Grosbach
committed
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
let Uses = [CPSR] in {
def ATOMIC_LOAD_ADD_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_SUB_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_AND_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_OR_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_XOR_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_NAND_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_ADD_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_SUB_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_AND_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_OR_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_XOR_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_NAND_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!",
[(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_ADD_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_SUB_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_AND_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_OR_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_XOR_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_NAND_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
[(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_SWAP_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
"${:comment} ATOMIC_SWAP_I8 PSEUDO!",
[(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>;
def ATOMIC_SWAP_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
"${:comment} ATOMIC_SWAP_I16 PSEUDO!",
[(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>;
def ATOMIC_SWAP_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary,
"${:comment} ATOMIC_SWAP_I32 PSEUDO!",
[(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>;
def ATOMIC_CMP_SWAP_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
"${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!",
[(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>;
def ATOMIC_CMP_SWAP_I16 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
"${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!",
[(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>;
def ATOMIC_CMP_SWAP_I32 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary,
"${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
[(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>;
}
Jim Grosbach
committed
}
let mayLoad = 1 in {
def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
"ldrexb", "\t$dest, [$ptr]",
[]>;
def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
"ldrexh", "\t$dest, [$ptr]",
[]>;
def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary,
"ldrex", "\t$dest, [$ptr]",
[]>;
def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
NoItinerary,
"ldrexd", "\t$dest, $dest2, [$ptr]",
[]>;
Jim Grosbach
committed
}
let mayStore = 1, Constraints = "@earlyclobber $success" in {
Jim Grosbach
committed
def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
Jim Grosbach
committed
"strexb", "\t$success, $src, [$ptr]",
[]>;
def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
NoItinerary,
"strexh", "\t$success, $src, [$ptr]",
[]>;
def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
Jim Grosbach
committed
"strex", "\t$success, $src, [$ptr]",
[]>;
def STREXD : AIstrex<0b01, (outs GPR:$success),
(ins GPR:$src, GPR:$src2, GPR:$ptr),
NoItinerary,
"strexd", "\t$success, $src, $src2, [$ptr]",
[]>;
Jim Grosbach
committed
}
// Clear-Exclusive is for disassembly only.
def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV7]> {
let Inst{31-20} = 0xf57;
let Inst{7-4} = 0b0001;
}
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
let mayLoad = 1 in {
def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
"swp", "\t$dst, $src, [$ptr]",
[/* For disassembly only; pattern left blank */]> {
let Inst{27-23} = 0b00010;
let Inst{22} = 0; // B = 0
let Inst{21-20} = 0b00;
let Inst{7-4} = 0b1001;
}
def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
"swpb", "\t$dst, $src, [$ptr]",
[/* For disassembly only; pattern left blank */]> {
let Inst{27-23} = 0b00010;
let Inst{22} = 1; // B = 1
let Inst{21-20} = 0b00;
let Inst{7-4} = 0b1001;
}
}
Lauro Ramos Venancio
committed
//===----------------------------------------------------------------------===//
// TLS Instructions
//
// __aeabi_read_tp preserves the registers r1-r3.
Evan Cheng
committed
let isCall = 1,
Defs = [R0, R12, LR, CPSR] in {
David Goodwin
committed
def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
Evan Cheng
committed
"bl\t__aeabi_read_tp",
Lauro Ramos Venancio
committed
[(set R0, ARMthread_pointer)]>;
}
Jim Grosbach
committed
//===----------------------------------------------------------------------===//
// SJLJ Exception handling intrinsics
// eh_sjlj_setjmp() is an instruction sequence to store the return
// address and save #0 in R0 for the non-longjmp case.
Jim Grosbach
committed
// Since by its nature we may be coming from some other function to get
// here, and we're using the stack frame for the containing function to
// save/restore registers, we can't keep anything live in regs across
// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
Jim Grosbach
committed
// when we get here from a longjmp(). We force everthing out of registers
// except for our own input by listing the relevant registers in Defs. By
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved resgisters, which is exactly what we want.
// A constant value is passed in $val, and we use the location as a scratch.
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
D31 ], hasSideEffects = 1, isBarrier = 1 in {
def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
David Goodwin
committed
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
"add\t$val, pc, #8\t${:comment} eh_setjmp begin\n\t"
"str\t$val, [$src, #+4]\n\t"
"mov\tr0, #0\n\t"
"add\tpc, pc, #0\n\t"
"mov\tr0, #1 ${:comment} eh_setjmp end", "",
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
Requires<[IsARM, HasVFP2]>;
}
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
hasSideEffects = 1, isBarrier = 1 in {
def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val),
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
"add\t$val, pc, #8\n ${:comment} eh_setjmp begin\n\t"
"str\t$val, [$src, #+4]\n\t"
"mov\tr0, #0\n\t"
"add\tpc, pc, #0\n\t"
"mov\tr0, #1 ${:comment} eh_setjmp end", "",
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
Requires<[IsARM, NoVFP]>;
Jim Grosbach
committed
}
// FIXME: Non-Darwin version(s)
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
Defs = [ R7, LR, SP ] in {
def Int_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
"ldr\tsp, [$src, #8]\n\t"
"ldr\t$scratch, [$src, #4]\n\t"
"ldr\tr7, [$src]\n\t"
"bx\t$scratch", "",
[(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
Requires<[IsARM, IsDarwin]>;
}
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
let isReMaterializable = 1 in
def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src),
Pseudo, IIC_iMOVi,
Evan Cheng
committed
"mov", "\t$dst, $src",
Evan Cheng
committed
[(set GPR:$dst, so_imm2part:$src)]>,
Requires<[IsARM, NoV6T2]>;
def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
(ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
(so_imm2part_2 imm:$RHS))>;
def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
(EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
(so_imm2part_2 imm:$RHS))>;
Jim Grosbach
committed
def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS),
(ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
(so_imm2part_2 imm:$RHS))>;
Jim Grosbach
committed
def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS),
(SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)),
(so_neg_imm2part_2 imm:$RHS))>;
Evan Cheng
committed
// 32-bit immediate using movw + movt.
Chris Lattner
committed
// This is a single pseudo instruction, the benefit is that it can be remat'd
// as a single unit instead of having to handle reg inputs.
// FIXME: Remove this when we can do generalized remat.
Evan Cheng
committed
let isReMaterializable = 1 in
def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
"movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
Evan Cheng
committed
[(set GPR:$dst, (i32 imm:$src))]>,
Requires<[IsARM, HasV6T2]>;
// ConstantPool, GlobalAddress, and JumpTable
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
Requires<[IsARM, DontUseMovt]>;
def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>,
Requires<[IsARM, UseMovt]>;
def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
(LEApcrelJT tjumptable:$dst, imm:$id)>;
def : ARMPat<(ARMtcret tcGPR:$dst),
(TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>;
def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
(TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
(TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>;
def : ARMPat<(ARMtcret tcGPR:$dst),
(TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>;
def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)),
(TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
def : ARMPat<(ARMtcret (i32 texternalsym:$dst)),
(TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>;
def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
Requires<[IsARM, IsNotDarwin]>;
def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
Requires<[IsARM, IsDarwin]>;
// zextload i1 -> zextload i8
def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
// extload -> zextload
def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
// smul* and smla*
def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
(sra (shl GPR:$b, (i32 16)), (i32 16))),
(SMULBB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
(SMULBB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
(sra GPR:$b, (i32 16))),
(SMULBT GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
(SMULBT GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
(sra (shl GPR:$b, (i32 16)), (i32 16))),
(SMULTB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
(SMULTB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
(i32 16)),
(SMULWB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
(SMULWB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
(sra (shl GPR:$b, (i32 16)), (i32 16)))),
(SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul sext_16_node:$a, sext_16_node:$b)),
(SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
(sra GPR:$b, (i32 16)))),
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra GPR:$a, (i32 16)),
(sra (shl GPR:$b, (i32 16)), (i32 16)))),
(SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
(SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
(i32 16))),
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
//===----------------------------------------------------------------------===//
// Thumb Support
//
//===----------------------------------------------------------------------===//
// Thumb2 Support
//
include "ARMInstrThumb2.td"
//===----------------------------------------------------------------------===//
// Floating Point Support
//
//===----------------------------------------------------------------------===//
// Advanced SIMD (NEON) Support
//
include "ARMInstrNEON.td"
//===----------------------------------------------------------------------===//
// Coprocessor Instructions. For disassembly only.
//
def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{4} = 0;
}
def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{4} = 0;
}
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
class ACI<dag oops, dag iops, string opc, string asm>
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
opc, asm, "", [/* For disassembly only; pattern left blank */]> {
let Inst{27-25} = 0b110;
}
multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
def _OFFSET : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
opc, "\tp$cop, cr$CRd, $addr"> {
let Inst{31-28} = op31_28;
let Inst{24} = 1; // P = 1
let Inst{21} = 0; // W = 0
let Inst{22} = 0; // D = 0
let Inst{20} = load;
}
def _PRE : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
opc, "\tp$cop, cr$CRd, $addr!"> {
let Inst{31-28} = op31_28;
let Inst{24} = 1; // P = 1
let Inst{21} = 1; // W = 1
let Inst{22} = 0; // D = 0
let Inst{20} = load;
}
def _POST : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
opc, "\tp$cop, cr$CRd, [$base], $offset"> {
let Inst{31-28} = op31_28;
let Inst{24} = 0; // P = 0
let Inst{21} = 1; // W = 1
let Inst{22} = 0; // D = 0
let Inst{20} = load;
}
def _OPTION : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
opc, "\tp$cop, cr$CRd, [$base], $option"> {
let Inst{31-28} = op31_28;
let Inst{24} = 0; // P = 0
let Inst{23} = 1; // U = 1
let Inst{21} = 0; // W = 0
let Inst{22} = 0; // D = 0
let Inst{20} = load;
}
def L_OFFSET : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
Johnny Chen
committed
!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> {
let Inst{31-28} = op31_28;
let Inst{24} = 1; // P = 1
let Inst{21} = 0; // W = 0
let Inst{22} = 1; // D = 1
let Inst{20} = load;
}
def L_PRE : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
Johnny Chen
committed
!strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
let Inst{31-28} = op31_28;
let Inst{24} = 1; // P = 1
let Inst{21} = 1; // W = 1
let Inst{22} = 1; // D = 1
let Inst{20} = load;
}
def L_POST : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
Johnny Chen
committed
!strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
let Inst{31-28} = op31_28;
let Inst{24} = 0; // P = 0
let Inst{21} = 1; // W = 1
let Inst{22} = 1; // D = 1
let Inst{20} = load;
}
def L_OPTION : ACI<(outs),
(ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
Johnny Chen
committed
!strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
let Inst{31-28} = op31_28;
let Inst{24} = 0; // P = 0
let Inst{23} = 1; // U = 1
let Inst{21} = 0; // W = 0
let Inst{22} = 1; // D = 1
let Inst{20} = load;
}
}
defm LDC : LdStCop<{?,?,?,?}, 1, "ldc">;
defm LDC2 : LdStCop<0b1111, 1, "ldc2">;
defm STC : LdStCop<{?,?,?,?}, 0, "stc">;
defm STC2 : LdStCop<0b1111, 0, "stc2">;
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{20} = 0;
let Inst{4} = 1;
}
def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{20} = 0;
let Inst{4} = 1;
}
def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{20} = 1;
let Inst{4} = 1;
}
def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{20} = 1;
let Inst{4} = 1;
}
def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0100;
}
def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{23-20} = 0b0100;
}
def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0101;
}
def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-28} = 0b1111;
let Inst{23-20} = 0b0101;
}
//===----------------------------------------------------------------------===//
// Move between special register and ARM core register -- for disassembly only
//
def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0000;
let Inst{7-4} = 0b0000;
}