Newer
Older
def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
Pseudo, NoItinerary,
"dmb", "",
Jim Grosbach
committed
Requires<[IsThumb2]> {
let Inst{31-4} = 0xF3BF8F5;
// FIXME: add support for options other than a full system DMB
let Inst{3-0} = 0b1111;
}
def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
Pseudo, NoItinerary,
"dsb", "",
Jim Grosbach
committed
Requires<[IsThumb2]> {
let Inst{31-4} = 0xF3BF8F4;
// FIXME: add support for options other than a full system DSB
let Inst{3-0} = 0b1111;
}
}
Johnny Chen
committed
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
// Helper class for multiclass T2MemB -- for disassembly only
class T2I_memb<string opc, string asm>
: T2I<(outs), (ins), NoItinerary, opc, asm,
[/* For disassembly only; pattern left blank */]>,
Requires<[IsThumb2, HasV7]> {
let Inst{31-20} = 0xf3b;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
multiclass T2MemB<bits<4> op7_4, string opc> {
def st : T2I_memb<opc, "\tst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1110;
}
def ish : T2I_memb<opc, "\tish"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1011;
}
def ishst : T2I_memb<opc, "\tishst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1010;
}
def nsh : T2I_memb<opc, "\tnsh"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0111;
}
def nshst : T2I_memb<opc, "\tnshst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0110;
}
def osh : T2I_memb<opc, "\tosh"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0011;
}
def oshst : T2I_memb<opc, "\toshst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0010;
}
}
// These DMB variants are for disassembly only.
defm t2DMB : T2MemB<0b0101, "dmb">;
// These DSB variants are for disassembly only.
defm t2DSB : T2MemB<0b0100, "dsb">;
// ISB has only full system option -- for disassembly only
def t2ISBsy : T2I_memb<"isb", ""> {
let Inst{7-4} = 0b0110;
let Inst{3-0} = 0b1111;
}
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin, string opc, string asm, string cstr,
list<dag> pattern, bits<4> rt2 = 0b1111>
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{11-8} = rt2;
let Inst{7-6} = 0b01;
let Inst{5-4} = opcod;
let Inst{3-0} = 0b1111;
}
class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin, string opc, string asm, string cstr,
list<dag> pattern, bits<4> rt2 = 0b1111>
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001100;
let Inst{11-8} = rt2;
let Inst{7-6} = 0b01;
let Inst{5-4} = opcod;
}
let mayLoad = 1 in {
def t2LDREXB : T2I_ldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
"", []>;
def t2LDREXH : T2I_ldrex<0b01, (outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
"", []>;
def t2LDREX : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary,
"ldrex", "\t$dest, [$ptr]", "",
[]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000101;
let Inst{11-8} = 0b1111;
let Inst{7-0} = 0b00000000; // imm8 = 0
}
def t2LDREXD : T2I_ldrex<0b11, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"ldrexd", "\t$dest, $dest2, [$ptr]", "",
[], {?, ?, ?, ?}>;
let mayStore = 1, Constraints = "@earlyclobber $success" in {
def t2STREXB : T2I_strex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexb", "\t$success, $src, [$ptr]", "", []>;
def t2STREXH : T2I_strex<0b01, (outs GPR:$success), (ins GPR:$src, GPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexh", "\t$success, $src, [$ptr]", "", []>;
def t2STREX : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strex", "\t$success, $src, [$ptr]", "",
[]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000100;
let Inst{7-0} = 0b00000000; // imm8 = 0
}
def t2STREXD : T2I_strex<0b11, (outs GPR:$success),
(ins GPR:$src, GPR:$src2, GPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexd", "\t$success, $src, $src2, [$ptr]", "", [],
{?, ?, ?, ?}>;
// Clear-Exclusive is for disassembly only.
def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV7]> {
let Inst{31-20} = 0xf3b;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
let Inst{7-4} = 0b0010;
}
David Goodwin
committed
//===----------------------------------------------------------------------===//
// TLS Instructions
//
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, R12, LR, CPSR] in {
David Goodwin
committed
def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
Evan Cheng
committed
"bl\t__aeabi_read_tp",
[(set R0, ARMthread_pointer)]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b11;
let Inst{12} = 1;
}
David Goodwin
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.
// 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
// 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.
// The current SP is passed in $val, and we reuse the reg 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 ] in {
def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
AddrModeNone, SizeSpecial, NoItinerary,
"str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
"\tmov\t$val, pc\n"
"\tadds\t$val, #9\n"
"\tstr\t$val, [$src, #4]\n"
Evan Cheng
committed
"\tmovs\tr0, #0\n"
"\tb\t1f\n"
"\tmovs\tr0, #1\t@ end eh.setjmp\n"
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
//===----------------------------------------------------------------------===//
// Control-Flow Instructions
//
// FIXME: remove when we have a way to marking a MI with these properties.
// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
// operand list.
// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Cheng
committed
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
Evan Cheng
committed
IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
[]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
let Inst{21} = ?; // The W bit.
let Inst{20} = 1; // Load
}
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
David Goodwin
committed
def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng
committed
"b.w\t$target",
[(br bb:$target)]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b10;
let Inst{12} = 1;
}
Evan Cheng
committed
let isNotDuplicable = 1, isIndirectBranch = 1 in {
def t2BR_JT :
Evan Cheng
committed
T2JTI<(outs),
(ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
Evan Cheng
committed
IIC_Br, "mov\tpc, $target\n$jt",
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0100100;
let Inst{19-16} = 0b1111;
let Inst{14-12} = 0b000;
let Inst{11-8} = 0b1111; // Rd = pc
let Inst{7-4} = 0b0000;
}
Evan Cheng
committed
// FIXME: Add a non-pc based case that can be predicated.
Evan Cheng
committed
def t2TBB :
Evan Cheng
committed
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
IIC_Br, "tbb\t$index\n$jt", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0000; // B form
}
Evan Cheng
committed
def t2TBH :
Evan Cheng
committed
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
IIC_Br, "tbh\t$index\n$jt", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0001; // H form
}
Johnny Chen
committed
// Generic versions of the above two instructions, for disassembly only
def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
"tbb", "\t[$a, $b]", []>{
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0000; // B form
}
def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
"tbh", "\t[$a, $b, lsl #1]", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0001; // H form
}
Evan Cheng
committed
} // isNotDuplicable, isIndirectBranch
} // isBranch, isTerminator, isBarrier
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
// a two-value operand where a dag node expects two operands. :(
let isBranch = 1, isTerminator = 1 in
David Goodwin
committed
def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng
committed
"b", ".w\t$target",
[/*(ARMbrcond bb:$target, imm:$cc)*/]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
Evan Cheng
committed
// IT block
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
AddrModeNone, Size2Bytes, IIC_iALUx,
"it$mask\t$cc", "", []> {
// 16-bit instruction.
Johnny Chen
committed
let Inst{31-16} = 0x0000;
let Inst{15-8} = 0b10111111;
}
// Branch and Exchange Jazelle -- for disassembly only
// Rm = Inst{19-16}
def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-20} = 0b111100;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
Johnny Chen
committed
// Change Processor State is a system instruction -- for disassembly only.
// The singleton $opt operand contains the following information:
// opt{4-0} = mode from Inst{4-0}
// opt{5} = changemode from Inst{17}
// opt{8-6} = AIF from Inst{8-6}
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
def t2CPS : T2XI<(outs),(ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-20} = 0b111010;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
// Secure Monitor Call is a system instruction -- for disassembly only
// Option = Inst{19-16}
def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26-20} = 0b1111111;
let Inst{15-12} = 0b1000;
}
// Store Return State is a system instruction -- for disassembly only
def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000010; // W = 1
}
def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000000; // W = 0
}
def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011010; // W = 1
}
def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011000; // W = 0
}
// Return From Exception is a system instruction -- for disassembly only
def t2RFEDBW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfedb", "\t$base!",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000011; // W = 1
}
def t2RFEDB : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeab", "\t$base",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000001; // W = 0
}
def t2RFEIAW : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base!",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011011; // W = 1
}
def t2RFEIA : T2I<(outs), (ins GPR:$base), NoItinerary, "rfeia", "\t$base",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011001; // W = 0
}
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
Jim Grosbach
committed
// Two piece so_imms.
def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
(t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
(t2_so_imm2part_2 imm:$RHS))>;
def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
(t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
(t2_so_imm2part_2 imm:$RHS))>;
def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
(t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
(t2_so_imm2part_2 imm:$RHS))>;
Jim Grosbach
committed
def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
(t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
(t2_so_neg_imm2part_2 imm:$RHS))>;
Jim Grosbach
committed
Evan Cheng
committed
// 32-bit immediate using movw + movt.
// This is a single pseudo instruction to make it re-materializable. Remove
// when we can do generalized remat.
let isReMaterializable = 1 in
def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
Evan Cheng
committed
"movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
Evan Cheng
committed
[(set GPR:$dst, (i32 imm:$src))]>;
Evan Cheng
committed
// ConstantPool, GlobalAddress, and JumpTable
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
Requires<[IsThumb2, DontUseMovt]>;
def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
Requires<[IsThumb2, UseMovt]>;
def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Cheng
committed
// Pseudo instruction that combines ldr from constpool and add pc. This should
// be expanded into two instructions late to allow if-conversion and
// scheduling.
let canFoldAsLoad = 1, isReMaterializable = 1 in
Evan Cheng
committed
def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
imm:$cp))]>,
Requires<[IsThumb2]>;
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
//===----------------------------------------------------------------------===//
// Move between special register and ARM core register -- for disassembly only
//
// Rd = Instr{11-8}
def t2MRS : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11111;
let Inst{20} = 0; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// Rd = Instr{11-8}
def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11111;
let Inst{20} = 1; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// FIXME: mask is ignored for the time being.
// Rn = Inst{19-16}
def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11100;
let Inst{20} = 0; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// FIXME: mask is ignored for the time being.
// Rn = Inst{19-16}
def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11100;
let Inst{20} = 1; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}