Newer
Older
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 : AI<(ops GPR:$dst, 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]>;
// 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, 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...
//
defm CMP : AI1_bin0_irs<"cmp", BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
defm CMN : AI1_bin0_irs<"cmn", BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
(CMNri GPR:$src, so_imm_neg:$imm)>;
// Note that TST/TEQ don't set all the same flags that CMP does!
Lauro Ramos Venancio
committed
defm TST : AI1_bin0_irs<"tst", BinOpFrag<(ARMcmpNZ (and node:$LHS, node:$RHS), 0)>>;
defm TEQ : AI1_bin0_irs<"teq", BinOpFrag<(ARMcmpNZ (xor node:$LHS, node:$RHS), 0)>>;
defm CMPnz : AI1_bin0_irs<"cmp", BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
defm CMNnz : AI1_bin0_irs<"cmn", BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
def : ARMPat<(ARMcmpNZ GPR:$src, so_imm_neg:$imm),
(CMNri GPR:$src, so_imm_neg:$imm)>;
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
// Conditional moves
def MOVCCr : AI<(ops GPR:$dst, GPR:$false, GPR:$true, CCOp:$cc),
"mov$cc $dst, $true",
[(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc))]>,
RegConstraint<"$false = $dst">;
def MOVCCs : AI<(ops GPR:$dst, GPR:$false, so_reg:$true, CCOp:$cc),
"mov$cc $dst, $true",
[(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true,imm:$cc))]>,
RegConstraint<"$false = $dst">;
def MOVCCi : AI<(ops GPR:$dst, GPR:$false, so_imm:$true, CCOp:$cc),
"mov$cc $dst, $true",
[(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true,imm:$cc))]>,
RegConstraint<"$false = $dst">;
// LEApcrel - Load a pc-relative address into a register without offending the
// assembler.
def LEApcrel : AI1<(ops GPR:$dst, i32imm:$label),
!strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
"${:private}PCRELL${:uid}+8))\n"),
!strconcat("${:private}PCRELL${:uid}:\n\t",
"add $dst, pc, #PCRELV${:uid}")),
[]>;
def LEApcrelJT : AI1<(ops GPR:$dst, i32imm:$label, i32imm:$id),
!strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
"${:private}PCRELL${:uid}+8))\n"),
!strconcat("${:private}PCRELL${:uid}:\n\t",
"add $dst, pc, #PCRELV${:uid}")),
[]>;
Lauro Ramos Venancio
committed
//===----------------------------------------------------------------------===//
// TLS Instructions
//
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, R12, LR] in {
def TPsoft : AI<(ops),
"bl __aeabi_read_tp",
[(set R0, ARMthread_pointer)]>;
}
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
// ConstantPool, GlobalAddress, and JumpTable
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
(LEApcrelJT tjumptable:$dst, imm:$id)>;
let isReMaterializable = 1 in
def MOVi2pieces : AI1x2<(ops GPR:$dst, so_imm2part:$src),
"mov $dst, $src",
[(set GPR:$dst, so_imm2part:$src)]>;
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))>;
// Direct calls
def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
// 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)>;
// truncstore i1 -> truncstore i8
def : Pat<(truncstorei1 GPR:$src, addrmode2:$dst),
(STRB GPR:$src, addrmode2:$dst)>;
def : Pat<(pre_truncsti1 GPR:$src, GPR:$base, am2offset:$offset),
(STRB_PRE GPR:$src, GPR:$base, am2offset:$offset)>;
def : Pat<(post_truncsti1 GPR:$src, GPR:$base, am2offset:$offset),
(STRB_POST GPR:$src, GPR:$base, am2offset:$offset)>;
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
// smul* and smla*
def : ARMV5TEPat<(mul (sra (shl GPR:$a, 16), 16), (sra (shl GPR:$b, 16), 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, 16), 16), (sra GPR:$b, 16)),
(SMULBT GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, 16)),
(SMULBT GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul (sra GPR:$a, 16), (sra (shl GPR:$b, 16), 16)),
(SMULTB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(mul (sra GPR:$a, 16), sext_16_node:$b),
(SMULTB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, 16), 16)), 16),
(SMULWB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), 16),
(SMULWB GPR:$a, GPR:$b)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra (shl GPR:$a, 16), 16),
(sra (shl GPR:$b, 16), 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, 16), 16), (sra GPR:$b, 16))),
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul sext_16_node:$a, (sra GPR:$b, 16))),
(SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra GPR:$a, 16), (sra (shl GPR:$b, 16), 16))),
(SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(mul (sra GPR:$a, 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, 16), 16)), 16)),
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
def : ARMV5TEPat<(add GPR:$acc,
(sra (mul GPR:$a, sext_16_node:$b), 16)),
(SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
//===----------------------------------------------------------------------===//
// Thumb Support
//
//===----------------------------------------------------------------------===//
// Floating Point Support
//