// DWARF debugging Pseudo Instructions
//===----------------------------------------------------------------------===//
-def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
- "${:comment} .loc $file, $line, $col",
- [(dwarf_loc (i32 imm:$line), (i32 imm:$col),
- (i32 imm:$file))]>;
+def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
+ ".loc $file, $line, $col",
+ [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
//===----------------------------------------------------------------------===//
// Loads:
def v4f32: LoadDFormVec<v4f32>;
def v2f64: LoadDFormVec<v2f64>;
+ def v2i32: LoadDFormVec<v2i32>;
+
def r128: LoadDForm<GPRC>;
def r64: LoadDForm<R64C>;
def r32: LoadDForm<R32C>;
def v4f32: LoadAFormVec<v4f32>;
def v2f64: LoadAFormVec<v2f64>;
+ def v2i32: LoadAFormVec<v2i32>;
+
def r128: LoadAForm<GPRC>;
def r64: LoadAForm<R64C>;
def r32: LoadAForm<R32C>;
def v4f32: LoadXFormVec<v4f32>;
def v2f64: LoadXFormVec<v2f64>;
+ def v2i32: LoadXFormVec<v2i32>;
+
def r128: LoadXForm<GPRC>;
def r64: LoadXForm<R64C>;
def r32: LoadXForm<R32C>;
def v4f32: StoreDFormVec<v4f32>;
def v2f64: StoreDFormVec<v2f64>;
+ def v2i32: StoreDFormVec<v2i32>;
+
def r128: StoreDForm<GPRC>;
def r64: StoreDForm<R64C>;
def r32: StoreDForm<R32C>;
def v4f32: StoreAFormVec<v4f32>;
def v2f64: StoreAFormVec<v2f64>;
+ def v2i32: StoreAFormVec<v2i32>;
+
def r128: StoreAForm<GPRC>;
def r64: StoreAForm<R64C>;
def r32: StoreAForm<R32C>;
def v4f32: StoreXFormVec<v4f32>;
def v2f64: StoreXFormVec<v2f64>;
+ def v2i32: StoreXFormVec<v2i32>;
+
def r128: StoreXForm<GPRC>;
def r64: StoreXForm<R64C>;
def r32: StoreXForm<R32C>;
class AIInst<dag OOL, dag IOL, list<dag> pattern>:
RI10Form<0b00111000, OOL, IOL,
- "ai\t$rT, $rA, $val", IntegerOp,
- pattern>;
+ "ai\t$rT, $rA, $val", IntegerOp,
+ pattern>;
class AIVecInst<ValueType vectype, PatLeaf immpred>:
AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
- [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>;
+ [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>;
class AIFPVecInst<ValueType vectype, PatLeaf immpred>:
AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
class AIRegInst<RegisterClass rclass, PatLeaf immpred>:
AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val),
- [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>;
+ [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>;
// This is used to add epsilons to floating point numbers in the f32 fdiv code:
class AIFPInst<RegisterClass rclass, PatLeaf immpred>:
AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
multiclass AddImmediate {
def v4i32: AIVecInst<v4i32, v4i32SExt10Imm>;
class ADDXVecInst<ValueType vectype>:
ADDXInst<(outs VECREG:$rT),
(ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry),
- [(set (vectype VECREG:$rT),
- (SPUaddx (vectype VECREG:$rA), (vectype VECREG:$rB),
- (vectype VECREG:$rCarry)))]>,
+ [/* no pattern */]>,
RegConstraint<"$rCarry = $rT">,
NoEncode<"$rCarry">;
class ADDXRegInst<RegisterClass rclass>:
ADDXInst<(outs rclass:$rT),
(ins rclass:$rA, rclass:$rB, rclass:$rCarry),
- [(set rclass:$rT,
- (SPUaddx rclass:$rA, rclass:$rB, rclass:$rCarry))]>,
+ [/* no pattern */]>,
RegConstraint<"$rCarry = $rT">,
NoEncode<"$rCarry">;
class CGVecInst<ValueType vectype>:
CGInst<(outs VECREG:$rT),
(ins VECREG:$rA, VECREG:$rB),
- [(set (vectype VECREG:$rT),
- (SPUcarry_gen (vectype VECREG:$rA), (vectype VECREG:$rB)))]>;
+ [/* no pattern */]>;
class CGRegInst<RegisterClass rclass>:
CGInst<(outs rclass:$rT),
(ins rclass:$rA, rclass:$rB),
- [(set rclass:$rT,
- (SPUcarry_gen rclass:$rA, rclass:$rB))]>;
+ [/* no pattern */]>;
multiclass CarryGenerate {
def v2i64 : CGVecInst<v2i64>;
class SFXVecInst<ValueType vectype>:
SFXInst<(outs VECREG:$rT),
(ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry),
- [(set (vectype VECREG:$rT),
- (SPUsubx (vectype VECREG:$rA), (vectype VECREG:$rB),
- (vectype VECREG:$rCarry)))]>,
+ [/* no pattern */]>,
RegConstraint<"$rCarry = $rT">,
NoEncode<"$rCarry">;
class SFXRegInst<RegisterClass rclass>:
SFXInst<(outs rclass:$rT),
(ins rclass:$rA, rclass:$rB, rclass:$rCarry),
- [(set rclass:$rT,
- (SPUsubx rclass:$rA, rclass:$rB, rclass:$rCarry))]>,
+ [/* no pattern */]>,
RegConstraint<"$rCarry = $rT">,
NoEncode<"$rCarry">;
class BGVecInst<ValueType vectype>:
BGInst<(outs VECREG:$rT),
(ins VECREG:$rA, VECREG:$rB),
- [(set (vectype VECREG:$rT),
- (SPUborrow_gen (vectype VECREG:$rA), (vectype VECREG:$rB)))]>;
+ [/* no pattern */]>;
class BGRegInst<RegisterClass rclass>:
BGInst<(outs rclass:$rT),
(ins rclass:$rA, rclass:$rB),
- [(set rclass:$rT,
- (SPUborrow_gen rclass:$rA, rclass:$rB))]>;
+ [/* no pattern */]>;
multiclass BorrowGenerate {
def v4i32 : BGVecInst<v4i32>;
"mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv,
pattern>;
-def MPYAvec:
+def MPYAv4i32:
MPYAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
[(set (v4i32 VECREG:$rT),
(add (v4i32 (bitconvert (mul (v8i16 VECREG:$rA),
"mpys\t$rT, $rA, $rB", IntegerMulDiv,
[/* no pattern */]>;
-def MPYSvec:
+def MPYSv4i32:
MPYSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>;
def MPYSr16:
def MPYHHAr32:
MPYHHAInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>;
-// mpyhhu: Multiply high-high, unsigned
+// mpyhhu: Multiply high-high, unsigned, e.g.:
+//
+// +-------+-------+ +-------+-------+ +---------+
+// | a0 . a1 | x | b0 . b1 | = | a0 x b0 |
+// +-------+-------+ +-------+-------+ +---------+
+//
+// where a0, b0 are the upper 16 bits of the 32-bit word
class MPYHHUInst<dag OOL, dag IOL>:
RRForm<0b01110011110, OOL, IOL,
"mpyhhu\t$rT, $rA, $rB", IntegerMulDiv,
[/* no pattern */]>;
-def MPYHHUvec:
+def MPYHHUv4i32:
MPYHHUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>;
def MPYHHUr32:
class GBBRegInst<RegisterClass rclass, ValueType vectype>:
GBBInst<(outs rclass:$rT), (ins VECREG:$rA),
- [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
class GBBVecInst<ValueType vectype>:
GBBInst<(outs VECREG:$rT), (ins VECREG:$rA),
- [(set (vectype VECREG:$rT), (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
multiclass GatherBitsFromBytes {
def v16i8_r32: GBBRegInst<R32C, v16i8>;
class GBHRegInst<RegisterClass rclass, ValueType vectype>:
GBHInst<(outs rclass:$rT), (ins VECREG:$rA),
- [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
class GBHVecInst<ValueType vectype>:
GBHInst<(outs VECREG:$rT), (ins VECREG:$rA),
- [(set (vectype VECREG:$rT),
- (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
multiclass GatherBitsHalfword {
def v8i16_r32: GBHRegInst<R32C, v8i16>;
class GBRegInst<RegisterClass rclass, ValueType vectype>:
GBInst<(outs rclass:$rT), (ins VECREG:$rA),
- [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
class GBVecInst<ValueType vectype>:
GBInst<(outs VECREG:$rT), (ins VECREG:$rA),
- [(set (vectype VECREG:$rT),
- (SPUgatherbits (vectype VECREG:$rA)))]>;
+ [/* no pattern */]>;
multiclass GatherBitsWord {
def v4i32_r32: GBRegInst<R32C, v4i32>;
def fabs32: ANDInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
[/* Intentionally does not match a pattern */]>;
- def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
+ def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB),
[/* Intentionally does not match a pattern */]>;
- // Could use v4i32, but won't for clarity
def fabsvec: ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
[/* Intentionally does not match a pattern */]>;
RRForm<0b10000011010, OOL, IOL, "andc\t$rT, $rA, $rB",
IntegerOp, pattern>;
-class ANDCVecInst<ValueType vectype>:
+class ANDCVecInst<ValueType vectype, PatFrag vnot_frag = vnot>:
ANDCInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- [(set (vectype VECREG:$rT), (and (vectype VECREG:$rA),
- (vnot (vectype VECREG:$rB))))]>;
+ [(set (vectype VECREG:$rT),
+ (and (vectype VECREG:$rA),
+ (vnot_frag (vectype VECREG:$rB))))]>;
class ANDCRegInst<RegisterClass rclass>:
ANDCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB),
def r32: ANDCRegInst<R32C>;
def r16: ANDCRegInst<R16C>;
def r8: ANDCRegInst<R8C>;
+
+ // Sometimes, the xor pattern has a bitcast constant:
+ def v16i8_conv: ANDCVecInst<v16i8, vnot_conv>;
}
defm ANDC : AndComplement;
// These are effectively no-ops, but need to exist for proper type conversion
// and type coercion.
-class ORCvtForm<dag OOL, dag IOL>
+class ORCvtForm<dag OOL, dag IOL, list<dag> pattern = [/* no pattern */]>
: SPUInstr<OOL, IOL, "or\t$rT, $rA, $rA", IntegerOp> {
bits<7> RA;
bits<7> RT;
- let Pattern = [/* no pattern */];
+ let Pattern = pattern;
let Inst{0-10} = 0b10000010000;
let Inst{11-17} = RA;
class ORExtractElt<RegisterClass rclass>:
ORCvtForm<(outs rclass:$rT), (ins VECREG:$rA)>;
-class ORCvtRegGPRC<RegisterClass rclass>:
- ORCvtForm<(outs GPRC:$rT), (ins rclass:$rA)>;
-
-class ORCvtVecGPRC:
- ORCvtForm<(outs GPRC:$rT), (ins VECREG:$rA)>;
+/* class ORCvtRegGPRC<RegisterClass rclass>:
+ ORCvtForm<(outs GPRC:$rT), (ins rclass:$rA)>; */
-class ORCvtGPRCReg<RegisterClass rclass>:
- ORCvtForm<(outs rclass:$rT), (ins GPRC:$rA)>;
+/* class ORCvtGPRCReg<RegisterClass rclass>:
+ ORCvtForm<(outs rclass:$rT), (ins GPRC:$rA)>; */
-class ORCvtFormR32Reg<RegisterClass rclass>:
- ORCvtForm<(outs rclass:$rT), (ins R32C:$rA)>;
+class ORCvtFormR32Reg<RegisterClass rclass, list<dag> pattern = [ ]>:
+ ORCvtForm<(outs rclass:$rT), (ins R32C:$rA), pattern>;
-class ORCvtFormRegR32<RegisterClass rclass>:
- ORCvtForm<(outs R32C:$rT), (ins rclass:$rA)>;
+class ORCvtFormRegR32<RegisterClass rclass, list<dag> pattern = [ ]>:
+ ORCvtForm<(outs R32C:$rT), (ins rclass:$rA), pattern>;
-class ORCvtFormR64Reg<RegisterClass rclass>:
- ORCvtForm<(outs rclass:$rT), (ins R64C:$rA)>;
+class ORCvtFormR64Reg<RegisterClass rclass, list<dag> pattern = [ ]>:
+ ORCvtForm<(outs rclass:$rT), (ins R64C:$rA), pattern>;
-class ORCvtFormRegR64<RegisterClass rclass>:
- ORCvtForm<(outs R64C:$rT), (ins rclass:$rA)>;
+class ORCvtFormRegR64<RegisterClass rclass, list<dag> pattern = [ ]>:
+ ORCvtForm<(outs R64C:$rT), (ins rclass:$rA), pattern>;
class ORCvtGPRCVec:
ORCvtForm<(outs VECREG:$rT), (ins GPRC:$rA)>;
+class ORCvtVecGPRC:
+ ORCvtForm<(outs GPRC:$rT), (ins VECREG:$rA)>;
+
multiclass BitwiseOr
{
def v16i8: ORVecInst<v16i8>;
(v2f64 (bitconvert (or (v2i64 VECREG:$rA),
(v2i64 VECREG:$rB)))))]>;
- def r64: ORRegInst<R64C>;
- def r32: ORRegInst<R32C>;
- def r16: ORRegInst<R16C>;
- def r8: ORRegInst<R8C>;
+ def r128: ORRegInst<GPRC>;
+ def r64: ORRegInst<R64C>;
+ def r32: ORRegInst<R32C>;
+ def r16: ORRegInst<R16C>;
+ def r8: ORRegInst<R8C>;
// OR instructions used to copy f32 and f64 registers.
def f32: ORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
def f32_v4f32: ORExtractElt<R32FP>;
def f64_v2f64: ORExtractElt<R64FP>;
- // Conversion from GPRC to register
+ // Conversion from vector to GPRC
+ def i128_vec: ORCvtVecGPRC;
+
+ // Conversion from GPRC to vector
+ def vec_i128: ORCvtGPRCVec;
+
+/*
+ // Conversion from register to GPRC
def i128_r64: ORCvtRegGPRC<R64C>;
def i128_f64: ORCvtRegGPRC<R64FP>;
def i128_r32: ORCvtRegGPRC<R32C>;
def i128_r16: ORCvtRegGPRC<R16C>;
def i128_r8: ORCvtRegGPRC<R8C>;
- // Conversion from GPRC to vector
- def i128_vec: ORCvtVecGPRC;
-
- // Conversion from register to GPRC
+ // Conversion from GPRC to register
def r64_i128: ORCvtGPRCReg<R64C>;
def f64_i128: ORCvtGPRCReg<R64FP>;
def r32_i128: ORCvtGPRCReg<R32C>;
def f32_i128: ORCvtGPRCReg<R32FP>;
def r16_i128: ORCvtGPRCReg<R16C>;
def r8_i128: ORCvtGPRCReg<R8C>;
-
- // Conversion from vector to GPRC
- def vec_i128: ORCvtGPRCVec;
-
+*/
+/*
// Conversion from register to R32C:
- def r16_r32: ORCvtFormRegR32<R16C>;
- def r8_r32: ORCvtFormRegR32<R8C>;
+ def r32_r16: ORCvtFormRegR32<R16C>;
+ def r32_r8: ORCvtFormRegR32<R8C>;
// Conversion from R32C to register
def r32_r16: ORCvtFormR32Reg<R16C>;
def r32_r8: ORCvtFormR32Reg<R8C>;
+*/
- // Conversion from register to R64C:
+ // Conversion from R64C to register:
def r32_r64: ORCvtFormR64Reg<R32C>;
- def r16_r64: ORCvtFormR64Reg<R16C>;
- def r8_r64: ORCvtFormR64Reg<R8C>;
+ // def r16_r64: ORCvtFormR64Reg<R16C>;
+ // def r8_r64: ORCvtFormR64Reg<R8C>;
- // Conversion from R64C to register
+ // Conversion to R64C from register:
def r64_r32: ORCvtFormRegR64<R32C>;
- def r64_r16: ORCvtFormRegR64<R16C>;
- def r64_r8: ORCvtFormRegR64<R8C>;
+ // def r64_r16: ORCvtFormRegR64<R16C>;
+ // def r64_r8: ORCvtFormRegR64<R8C>;
+
+ // bitconvert patterns:
+ def r32_f32: ORCvtFormR32Reg<R32FP,
+ [(set R32FP:$rT, (bitconvert R32C:$rA))]>;
+ def f32_r32: ORCvtFormRegR32<R32FP,
+ [(set R32C:$rT, (bitconvert R32FP:$rA))]>;
+
+ def r64_f64: ORCvtFormR64Reg<R64FP,
+ [(set R64FP:$rT, (bitconvert R64C:$rA))]>;
+ def f64_r64: ORCvtFormRegR64<R64FP,
+ [(set R64C:$rT, (bitconvert R64FP:$rA))]>;
}
defm OR : BitwiseOr;
def v4i32: ORCVecInst<v4i32>;
def v2i64: ORCVecInst<v2i64>;
+ def r128: ORCRegInst<GPRC>;
def r64: ORCRegInst<R64C>;
def r32: ORCRegInst<R32C>;
def r16: ORCRegInst<R16C>;
def r16: XORRegInst<R16C>;
def r8: XORRegInst<R8C>;
- // Special forms for floating point instructions.
- // fneg and fabs require bitwise logical ops to manipulate the sign bit.
+ // XOR instructions used to negate f32 and f64 quantities.
def fneg32: XORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB),
- [/* no pattern */]>;
+ [/* no pattern */]>;
- def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB),
- [/* no pattern */]>;
+ def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB),
+ [/* no pattern */]>;
def fnegvec: XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- [/* no pattern, see fneg{32,64} */]>;
+ [/* no pattern, see fneg{32,64} */]>;
}
defm XOR : BitwiseExclusiveOr;
[(set R32C:$rT, (xor R32C:$rA, i32ImmSExt10:$val))]>;
// NAND:
-def NANDv16i8:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set (v16i8 VECREG:$rT), (vnot (and (v16i8 VECREG:$rA),
- (v16i8 VECREG:$rB))))]>;
-def NANDv8i16:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set (v8i16 VECREG:$rT), (vnot (and (v8i16 VECREG:$rA),
- (v8i16 VECREG:$rB))))]>;
-
-def NANDv4i32:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set (v4i32 VECREG:$rT), (vnot (and (v4i32 VECREG:$rA),
- (v4i32 VECREG:$rB))))]>;
+class NANDInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm<0b10010011000, OOL, IOL, "nand\t$rT, $rA, $rB",
+ IntegerOp, pattern>;
-def NANDr32:
- RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set R32C:$rT, (not (and R32C:$rA, R32C:$rB)))]>;
+class NANDVecInst<ValueType vectype>:
+ NANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
+ [(set (vectype VECREG:$rT), (vnot (and (vectype VECREG:$rA),
+ (vectype VECREG:$rB))))]>;
+class NANDRegInst<RegisterClass rclass>:
+ NANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB),
+ [(set rclass:$rT, (not (and rclass:$rA, rclass:$rB)))]>;
-def NANDr16:
- RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set R16C:$rT, (not (and R16C:$rA, R16C:$rB)))]>;
+multiclass BitwiseNand
+{
+ def v16i8: NANDVecInst<v16i8>;
+ def v8i16: NANDVecInst<v8i16>;
+ def v4i32: NANDVecInst<v4i32>;
+ def v2i64: NANDVecInst<v2i64>;
+
+ def r128: NANDRegInst<GPRC>;
+ def r64: NANDRegInst<R64C>;
+ def r32: NANDRegInst<R32C>;
+ def r16: NANDRegInst<R16C>;
+ def r8: NANDRegInst<R8C>;
+}
-def NANDr8:
- RRForm<0b10010010000, (outs R8C:$rT), (ins R8C:$rA, R8C:$rB),
- "nand\t$rT, $rA, $rB", IntegerOp,
- [(set R8C:$rT, (not (and R8C:$rA, R8C:$rB)))]>;
+defm NAND : BitwiseNand;
// NOR:
-def NORv16i8:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set (v16i8 VECREG:$rT), (vnot (or (v16i8 VECREG:$rA),
- (v16i8 VECREG:$rB))))]>;
-
-def NORv8i16:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set (v8i16 VECREG:$rT), (vnot (or (v8i16 VECREG:$rA),
- (v8i16 VECREG:$rB))))]>;
-def NORv4i32:
- RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set (v4i32 VECREG:$rT), (vnot (or (v4i32 VECREG:$rA),
- (v4i32 VECREG:$rB))))]>;
+class NORInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm<0b10010010000, OOL, IOL, "nor\t$rT, $rA, $rB",
+ IntegerOp, pattern>;
-def NORr32:
- RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set R32C:$rT, (not (or R32C:$rA, R32C:$rB)))]>;
+class NORVecInst<ValueType vectype>:
+ NORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
+ [(set (vectype VECREG:$rT), (vnot (or (vectype VECREG:$rA),
+ (vectype VECREG:$rB))))]>;
+class NORRegInst<RegisterClass rclass>:
+ NORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB),
+ [(set rclass:$rT, (not (or rclass:$rA, rclass:$rB)))]>;
-def NORr16:
- RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set R16C:$rT, (not (or R16C:$rA, R16C:$rB)))]>;
+multiclass BitwiseNor
+{
+ def v16i8: NORVecInst<v16i8>;
+ def v8i16: NORVecInst<v8i16>;
+ def v4i32: NORVecInst<v4i32>;
+ def v2i64: NORVecInst<v2i64>;
+
+ def r128: NORRegInst<GPRC>;
+ def r64: NORRegInst<R64C>;
+ def r32: NORRegInst<R32C>;
+ def r16: NORRegInst<R16C>;
+ def r8: NORRegInst<R8C>;
+}
-def NORr8:
- RRForm<0b10010010000, (outs R8C:$rT), (ins R8C:$rA, R8C:$rB),
- "nor\t$rT, $rA, $rB", IntegerOp,
- [(set R8C:$rT, (not (or R8C:$rA, R8C:$rB)))]>;
+defm NOR : BitwiseNor;
// Select bits:
class SELBInst<dag OOL, dag IOL, list<dag> pattern>:
RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC",
IntegerOp, pattern>;
-class SELBVecInst<ValueType vectype>:
+class SELBVecInst<ValueType vectype, PatFrag vnot_frag = vnot>:
SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
[(set (vectype VECREG:$rT),
(or (and (vectype VECREG:$rC), (vectype VECREG:$rB)),
- (and (vnot (vectype VECREG:$rC)),
+ (and (vnot_frag (vectype VECREG:$rC)),
(vectype VECREG:$rA))))]>;
class SELBVecVCondInst<ValueType vectype>:
def v16i8: SELBVecInst<v16i8>;
def v8i16: SELBVecInst<v8i16>;
def v4i32: SELBVecInst<v4i32>;
- def v2i64: SELBVecInst<v2i64>;
+ def v2i64: SELBVecInst<v2i64, vnot_conv>;
def r128: SELBRegInst<GPRC>;
def r64: SELBRegInst<R64C>;
def v2i64_vcond: SELBVecCondInst<v2i64>;
def v4f32_cond:
- SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
- [(set (v4f32 VECREG:$rT),
- (select (v4i32 VECREG:$rC),
- (v4f32 VECREG:$rB),
- (v4f32 VECREG:$rA)))]>;
+ SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+ [(set (v4f32 VECREG:$rT),
+ (select (v4i32 VECREG:$rC),
+ (v4f32 VECREG:$rB),
+ (v4f32 VECREG:$rA)))]>;
- // SELBr64_cond is defined further down, look for i64 comparisons
+ // SELBr64_cond is defined in SPU64InstrInfo.td
def r32_cond: SELBRegCondInst<R32C, R32C>;
def f32_cond: SELBRegCondInst<R32C, R32FP>;
def r16_cond: SELBRegCondInst<R16C, R16C>;
[(set (vectype VECREG:$rT),
(SPUvec_shl (vectype VECREG:$rA), R16C:$rB))]>;
-// $rB gets promoted to 32-bit register type when confronted with
-// this llvm assembly code:
-//
-// define i16 @shlh_i16_1(i16 %arg1, i16 %arg2) {
-// %A = shl i16 %arg1, %arg2
-// ret i16 %A
-// }
-
multiclass ShiftLeftHalfword
{
def v8i16: SHLHVecInst<v8i16>;
[(set (vectype VECREG:$rT),
(SPUshlquad_l_bits (vectype VECREG:$rA), R32C:$rB))]>;
+class SHLQBIRegInst<RegisterClass rclass>:
+ SHLQBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB),
+ [/* no pattern */]>;
+
multiclass ShiftLeftQuadByBits
{
def v16i8: SHLQBIVecInst<v16i8>;
def v4f32: SHLQBIVecInst<v4f32>;
def v2i64: SHLQBIVecInst<v2i64>;
def v2f64: SHLQBIVecInst<v2f64>;
+
+ def r128: SHLQBIRegInst<GPRC>;
}
defm SHLQBI : ShiftLeftQuadByBits;
defm SHLQBYI : ShiftLeftQuadBytesImm;
+class SHLQBYBIInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm<0b00111001111, OOL, IOL, "shlqbybi\t$rT, $rA, $rB",
+ RotateShift, pattern>;
+
+class SHLQBYBIVecInst<ValueType vectype>:
+ SHLQBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
+ [/* no pattern */]>;
+
+class SHLQBYBIRegInst<RegisterClass rclass>:
+ SHLQBYBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB),
+ [/* no pattern */]>;
+
+multiclass ShiftLeftQuadBytesBitCount
+{
+ def v16i8: SHLQBYBIVecInst<v16i8>;
+ def v8i16: SHLQBYBIVecInst<v8i16>;
+ def v4i32: SHLQBYBIVecInst<v4i32>;
+ def v4f32: SHLQBYBIVecInst<v4f32>;
+ def v2i64: SHLQBYBIVecInst<v2i64>;
+ def v2f64: SHLQBYBIVecInst<v2f64>;
+
+ def r128: SHLQBYBIRegInst<GPRC>;
+}
+
+defm SHLQBYBI : ShiftLeftQuadBytesBitCount;
+
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// Rotate halfword:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
(v4i32 v4i32SExt16Imm:$val)))]>;
def f32: CGTIInst<(outs R32C:$rT), (ins R32FP:$rA, s10imm_i32:$val),
- [/* no pattern */]>;
+ [/* no pattern */]>;
}
class CLGTBInst<dag OOL, dag IOL, list<dag> pattern> :
(fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
(v2f64 VECREG:$rC)))]>;
-// FNMS: - (a * b - c)
+// DFNMS: - (a * b - c)
// - (a * b) + c => c - (a * b)
-def FNMSf64 :
- RRForm<0b01111010110, (outs R64FP:$rT),
- (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
- "dfnms\t$rT, $rA, $rB", DPrecFP,
- [(set R64FP:$rT, (fsub R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>,
+
+class DFNMSInst<dag OOL, dag IOL, list<dag> pattern>:
+ RRForm<0b01111010110, OOL, IOL, "dfnms\t$rT, $rA, $rB",
+ DPrecFP, pattern>,
RegConstraint<"$rC = $rT">,
NoEncode<"$rC">;
-def : Pat<(fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)),
- (FNMSf64 R64FP:$rA, R64FP:$rB, R64FP:$rC)>;
+class DFNMSVecInst<list<dag> pattern>:
+ DFNMSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
+ pattern>;
-def FNMSv2f64 :
- RRForm<0b01111010110, (outs VECREG:$rT),
- (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
- "dfnms\t$rT, $rA, $rB", DPrecFP,
- [(set (v2f64 VECREG:$rT),
- (fsub (v2f64 VECREG:$rC),
- (fmul (v2f64 VECREG:$rA),
- (v2f64 VECREG:$rB))))]>,
- RegConstraint<"$rC = $rT">,
- NoEncode<"$rC">;
+class DFNMSRegInst<list<dag> pattern>:
+ DFNMSInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R64FP:$rC),
+ pattern>;
+
+multiclass DFMultiplySubtract
+{
+ def v2f64 : DFNMSVecInst<[(set (v2f64 VECREG:$rT),
+ (fsub (v2f64 VECREG:$rC),
+ (fmul (v2f64 VECREG:$rA),
+ (v2f64 VECREG:$rB))))]>;
+
+ def f64 : DFNMSRegInst<[(set R64FP:$rT,
+ (fsub R64FP:$rC,
+ (fmul R64FP:$rA, R64FP:$rB)))]>;
+}
-def : Pat<(fneg (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)),
- (v2f64 VECREG:$rC))),
- (FNMSv2f64 VECREG:$rA, VECREG:$rB, VECREG:$rC)>;
+defm DFNMS : DFMultiplySubtract;
// - (a * b + c)
// - (a * b) - c
def : Pat<(fneg R32FP:$rA),
(XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>;
-def : Pat<(fneg (v2f64 VECREG:$rA)),
- (XORfnegvec (v2f64 VECREG:$rA),
- (v2f64 (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80)))>;
-
-def : Pat<(fneg R64FP:$rA),
- (XORfneg64 R64FP:$rA,
- (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80))>;
-
// Floating point absolute value
+// Note: f64 fabs is custom-selected.
def : Pat<(fabs R32FP:$rA),
(ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>;
def : Pat<(fabs (v4f32 VECREG:$rA)),
(ANDfabsvec (v4f32 VECREG:$rA),
- (v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
-
-def : Pat<(fabs R64FP:$rA),
- (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>;
-
-def : Pat<(fabs (v2f64 VECREG:$rA)),
- (ANDfabsvec (v2f64 VECREG:$rA),
- (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>;
+ (IOHLv4i32 (ILHUv4i32 0x7fff), 0xffff))>;
//===----------------------------------------------------------------------===//
// Hint for branch instructions:
//===----------------------------------------------------------------------===//
// Bit conversions (type conversions between vector/packed types)
-// NOTE: Promotions are handled using the XS* instructions. Truncation
-// is not handled.
+// NOTE: Promotions are handled using the XS* instructions.
//===----------------------------------------------------------------------===//
def : Pat<(v16i8 (bitconvert (v8i16 VECREG:$src))), (v16i8 VECREG:$src)>;
def : Pat<(v16i8 (bitconvert (v4i32 VECREG:$src))), (v16i8 VECREG:$src)>;
def : Pat<(v2f64 (bitconvert (v2i64 VECREG:$src))), (v2f64 VECREG:$src)>;
def : Pat<(v2f64 (bitconvert (v2f64 VECREG:$src))), (v2f64 VECREG:$src)>;
-def : Pat<(f32 (bitconvert (i32 R32C:$src))), (f32 R32FP:$src)>;
-def : Pat<(f64 (bitconvert (i64 R64C:$src))), (f64 R64FP:$src)>;
+def : Pat<(i128 (bitconvert (v16i8 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+def : Pat<(i128 (bitconvert (v8i16 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+def : Pat<(i128 (bitconvert (v4i32 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+def : Pat<(i128 (bitconvert (v2i64 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+def : Pat<(i128 (bitconvert (v4f32 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+def : Pat<(i128 (bitconvert (v2f64 VECREG:$src))),
+ (ORi128_vec VECREG:$src)>;
+
+def : Pat<(v16i8 (bitconvert (i128 GPRC:$src))),
+ (v16i8 (ORvec_i128 GPRC:$src))>;
+def : Pat<(v8i16 (bitconvert (i128 GPRC:$src))),
+ (v8i16 (ORvec_i128 GPRC:$src))>;
+def : Pat<(v4i32 (bitconvert (i128 GPRC:$src))),
+ (v4i32 (ORvec_i128 GPRC:$src))>;
+def : Pat<(v2i64 (bitconvert (i128 GPRC:$src))),
+ (v2i64 (ORvec_i128 GPRC:$src))>;
+def : Pat<(v4f32 (bitconvert (i128 GPRC:$src))),
+ (v4f32 (ORvec_i128 GPRC:$src))>;
+def : Pat<(v2f64 (bitconvert (i128 GPRC:$src))),
+ (v2f64 (ORvec_i128 GPRC:$src))>;
//===----------------------------------------------------------------------===//
// Instruction patterns:
def : Pat<(i8 imm:$imm),
(ILHr8 imm:$imm)>;
-//===----------------------------------------------------------------------===//
-// Call instruction patterns:
-//===----------------------------------------------------------------------===//
-// Return void
-def : Pat<(ret),
- (RET)>;
-
//===----------------------------------------------------------------------===//
// Zero/Any/Sign extensions
//===----------------------------------------------------------------------===//
def : Pat<(add (SPUhi tconstpool:$in, 0), (SPUlo tconstpool:$in, 0)),
(IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>;
-// Instrinsics:
+// Intrinsics:
include "CellSDKIntrinsics.td"
// Various math operator instruction sequences
include "SPUMathInstr.td"