diff options
Diffstat (limited to 'lib/Target/CellSPU/SPUInstrInfo.td')
-rw-r--r-- | lib/Target/CellSPU/SPUInstrInfo.td | 4484 |
1 files changed, 0 insertions, 4484 deletions
diff --git a/lib/Target/CellSPU/SPUInstrInfo.td b/lib/Target/CellSPU/SPUInstrInfo.td deleted file mode 100644 index 117acd736a..0000000000 --- a/lib/Target/CellSPU/SPUInstrInfo.td +++ /dev/null @@ -1,4484 +0,0 @@ -//==- SPUInstrInfo.td - Describe the Cell SPU Instructions -*- tablegen -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Cell SPU Instructions: -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// TODO Items (not urgent today, but would be nice, low priority) -// -// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by -// concatenating the byte argument b as "bbbb". Could recognize this bit pattern -// in 16-bit and 32-bit constants and reduce instruction count. -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Pseudo instructions: -//===----------------------------------------------------------------------===// - -let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in { - def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm_i32:$amt), - "${:comment} ADJCALLSTACKDOWN", - [(callseq_start timm:$amt)]>; - def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm_i32:$amt), - "${:comment} ADJCALLSTACKUP", - [(callseq_end timm:$amt)]>; - def HBR_LABEL : Pseudo<(outs), (ins hbrtarget:$targ), - "$targ:\t${:comment}branch hint target",[ ]>; -} - -//===----------------------------------------------------------------------===// -// Loads: -// NB: The ordering is actually important, since the instruction selection -// will try each of the instructions in sequence, i.e., the D-form first with -// the 10-bit displacement, then the A-form with the 16 bit displacement, and -// finally the X-form with the register-register. -//===----------------------------------------------------------------------===// - -let canFoldAsLoad = 1 in { - class LoadDFormVec<ValueType vectype> - : RI10Form<0b00101100, (outs VECREG:$rT), (ins dformaddr:$src), - "lqd\t$rT, $src", - LoadStore, - [(set (vectype VECREG:$rT), (load dform_addr:$src))]> - { } - - class LoadDForm<RegisterClass rclass> - : RI10Form<0b00101100, (outs rclass:$rT), (ins dformaddr:$src), - "lqd\t$rT, $src", - LoadStore, - [(set rclass:$rT, (load dform_addr:$src))]> - { } - - multiclass LoadDForms - { - def v16i8: LoadDFormVec<v16i8>; - def v8i16: LoadDFormVec<v8i16>; - def v4i32: LoadDFormVec<v4i32>; - def v2i64: LoadDFormVec<v2i64>; - def v4f32: LoadDFormVec<v4f32>; - def v2f64: LoadDFormVec<v2f64>; - - def r128: LoadDForm<GPRC>; - def r64: LoadDForm<R64C>; - def r32: LoadDForm<R32C>; - def f32: LoadDForm<R32FP>; - def f64: LoadDForm<R64FP>; - def r16: LoadDForm<R16C>; - def r8: LoadDForm<R8C>; - } - - class LoadAFormVec<ValueType vectype> - : RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), - "lqa\t$rT, $src", - LoadStore, - [(set (vectype VECREG:$rT), (load aform_addr:$src))]> - { } - - class LoadAForm<RegisterClass rclass> - : RI16Form<0b100001100, (outs rclass:$rT), (ins addr256k:$src), - "lqa\t$rT, $src", - LoadStore, - [(set rclass:$rT, (load aform_addr:$src))]> - { } - - multiclass LoadAForms - { - def v16i8: LoadAFormVec<v16i8>; - def v8i16: LoadAFormVec<v8i16>; - def v4i32: LoadAFormVec<v4i32>; - def v2i64: LoadAFormVec<v2i64>; - def v4f32: LoadAFormVec<v4f32>; - def v2f64: LoadAFormVec<v2f64>; - - def r128: LoadAForm<GPRC>; - def r64: LoadAForm<R64C>; - def r32: LoadAForm<R32C>; - def f32: LoadAForm<R32FP>; - def f64: LoadAForm<R64FP>; - def r16: LoadAForm<R16C>; - def r8: LoadAForm<R8C>; - } - - class LoadXFormVec<ValueType vectype> - : RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), - "lqx\t$rT, $src", - LoadStore, - [(set (vectype VECREG:$rT), (load xform_addr:$src))]> - { } - - class LoadXForm<RegisterClass rclass> - : RRForm<0b00100011100, (outs rclass:$rT), (ins memrr:$src), - "lqx\t$rT, $src", - LoadStore, - [(set rclass:$rT, (load xform_addr:$src))]> - { } - - multiclass LoadXForms - { - def v16i8: LoadXFormVec<v16i8>; - def v8i16: LoadXFormVec<v8i16>; - def v4i32: LoadXFormVec<v4i32>; - def v2i64: LoadXFormVec<v2i64>; - def v4f32: LoadXFormVec<v4f32>; - def v2f64: LoadXFormVec<v2f64>; - - def r128: LoadXForm<GPRC>; - def r64: LoadXForm<R64C>; - def r32: LoadXForm<R32C>; - def f32: LoadXForm<R32FP>; - def f64: LoadXForm<R64FP>; - def r16: LoadXForm<R16C>; - def r8: LoadXForm<R8C>; - } - - defm LQA : LoadAForms; - defm LQD : LoadDForms; - defm LQX : LoadXForms; - -/* Load quadword, PC relative: Not much use at this point in time. - Might be of use later for relocatable code. It's effectively the - same as LQA, but uses PC-relative addressing. - def LQR : RI16Form<0b111001100, (outs VECREG:$rT), (ins s16imm:$disp), - "lqr\t$rT, $disp", LoadStore, - [(set VECREG:$rT, (load iaddr:$disp))]>; - */ -} - -//===----------------------------------------------------------------------===// -// Stores: -//===----------------------------------------------------------------------===// -class StoreDFormVec<ValueType vectype> - : RI10Form<0b00100100, (outs), (ins VECREG:$rT, dformaddr:$src), - "stqd\t$rT, $src", - LoadStore, - [(store (vectype VECREG:$rT), dform_addr:$src)]> -{ } - -class StoreDForm<RegisterClass rclass> - : RI10Form<0b00100100, (outs), (ins rclass:$rT, dformaddr:$src), - "stqd\t$rT, $src", - LoadStore, - [(store rclass:$rT, dform_addr:$src)]> -{ } - -multiclass StoreDForms -{ - def v16i8: StoreDFormVec<v16i8>; - def v8i16: StoreDFormVec<v8i16>; - def v4i32: StoreDFormVec<v4i32>; - def v2i64: StoreDFormVec<v2i64>; - def v4f32: StoreDFormVec<v4f32>; - def v2f64: StoreDFormVec<v2f64>; - - def r128: StoreDForm<GPRC>; - def r64: StoreDForm<R64C>; - def r32: StoreDForm<R32C>; - def f32: StoreDForm<R32FP>; - def f64: StoreDForm<R64FP>; - def r16: StoreDForm<R16C>; - def r8: StoreDForm<R8C>; -} - -class StoreAFormVec<ValueType vectype> - : RI16Form<0b0010010, (outs), (ins VECREG:$rT, addr256k:$src), - "stqa\t$rT, $src", - LoadStore, - [(store (vectype VECREG:$rT), aform_addr:$src)]>; - -class StoreAForm<RegisterClass rclass> - : RI16Form<0b001001, (outs), (ins rclass:$rT, addr256k:$src), - "stqa\t$rT, $src", - LoadStore, - [(store rclass:$rT, aform_addr:$src)]>; - -multiclass StoreAForms -{ - def v16i8: StoreAFormVec<v16i8>; - def v8i16: StoreAFormVec<v8i16>; - def v4i32: StoreAFormVec<v4i32>; - def v2i64: StoreAFormVec<v2i64>; - def v4f32: StoreAFormVec<v4f32>; - def v2f64: StoreAFormVec<v2f64>; - - def r128: StoreAForm<GPRC>; - def r64: StoreAForm<R64C>; - def r32: StoreAForm<R32C>; - def f32: StoreAForm<R32FP>; - def f64: StoreAForm<R64FP>; - def r16: StoreAForm<R16C>; - def r8: StoreAForm<R8C>; -} - -class StoreXFormVec<ValueType vectype> - : RRForm<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), - "stqx\t$rT, $src", - LoadStore, - [(store (vectype VECREG:$rT), xform_addr:$src)]> -{ } - -class StoreXForm<RegisterClass rclass> - : RRForm<0b00100100, (outs), (ins rclass:$rT, memrr:$src), - "stqx\t$rT, $src", - LoadStore, - [(store rclass:$rT, xform_addr:$src)]> -{ } - -multiclass StoreXForms -{ - def v16i8: StoreXFormVec<v16i8>; - def v8i16: StoreXFormVec<v8i16>; - def v4i32: StoreXFormVec<v4i32>; - def v2i64: StoreXFormVec<v2i64>; - def v4f32: StoreXFormVec<v4f32>; - def v2f64: StoreXFormVec<v2f64>; - - def r128: StoreXForm<GPRC>; - def r64: StoreXForm<R64C>; - def r32: StoreXForm<R32C>; - def f32: StoreXForm<R32FP>; - def f64: StoreXForm<R64FP>; - def r16: StoreXForm<R16C>; - def r8: StoreXForm<R8C>; -} - -defm STQD : StoreDForms; -defm STQA : StoreAForms; -defm STQX : StoreXForms; - -/* Store quadword, PC relative: Not much use at this point in time. Might - be useful for relocatable code. -def STQR : RI16Form<0b111000100, (outs), (ins VECREG:$rT, s16imm:$disp), - "stqr\t$rT, $disp", LoadStore, - [(store VECREG:$rT, iaddr:$disp)]>; -*/ - -//===----------------------------------------------------------------------===// -// Generate Controls for Insertion: -//===----------------------------------------------------------------------===// - -def CBD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "cbd\t$rT, $src", ShuffleOp, - [(set (v16i8 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CBX: RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src), - "cbx\t$rT, $src", ShuffleOp, - [(set (v16i8 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -def CHD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "chd\t$rT, $src", ShuffleOp, - [(set (v8i16 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CHX: RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src), - "chx\t$rT, $src", ShuffleOp, - [(set (v8i16 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -def CWD: RI7Form<0b01101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "cwd\t$rT, $src", ShuffleOp, - [(set (v4i32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CWX: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), - "cwx\t$rT, $src", ShuffleOp, - [(set (v4i32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -def CWDf32: RI7Form<0b01101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "cwd\t$rT, $src", ShuffleOp, - [(set (v4f32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CWXf32: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), - "cwx\t$rT, $src", ShuffleOp, - [(set (v4f32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -def CDD: RI7Form<0b11101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "cdd\t$rT, $src", ShuffleOp, - [(set (v2i64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CDX: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), - "cdx\t$rT, $src", ShuffleOp, - [(set (v2i64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -def CDDf64: RI7Form<0b11101111100, (outs VECREG:$rT), (ins shufaddr:$src), - "cdd\t$rT, $src", ShuffleOp, - [(set (v2f64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CDXf64: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), - "cdx\t$rT, $src", ShuffleOp, - [(set (v2f64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; - -//===----------------------------------------------------------------------===// -// Constant formation: -//===----------------------------------------------------------------------===// - -def ILHv8i16: - RI16Form<0b110000010, (outs VECREG:$rT), (ins s16imm:$val), - "ilh\t$rT, $val", ImmLoad, - [(set (v8i16 VECREG:$rT), (v8i16 v8i16SExt16Imm:$val))]>; - -def ILHr16: - RI16Form<0b110000010, (outs R16C:$rT), (ins s16imm:$val), - "ilh\t$rT, $val", ImmLoad, - [(set R16C:$rT, immSExt16:$val)]>; - -// Cell SPU doesn't have a native 8-bit immediate load, but ILH works ("with -// the right constant") -def ILHr8: - RI16Form<0b110000010, (outs R8C:$rT), (ins s16imm_i8:$val), - "ilh\t$rT, $val", ImmLoad, - [(set R8C:$rT, immSExt8:$val)]>; - -// IL does sign extension! - -class ILInst<dag OOL, dag IOL, list<dag> pattern>: - RI16Form<0b100000010, OOL, IOL, "il\t$rT, $val", - ImmLoad, pattern>; - -class ILVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: - ILInst<(outs VECREG:$rT), (ins immtype:$val), - [(set (vectype VECREG:$rT), (vectype xform:$val))]>; - -class ILRegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: - ILInst<(outs rclass:$rT), (ins immtype:$val), - [(set rclass:$rT, xform:$val)]>; - -multiclass ImmediateLoad -{ - def v2i64: ILVecInst<v2i64, s16imm_i64, v2i64SExt16Imm>; - def v4i32: ILVecInst<v4i32, s16imm_i32, v4i32SExt16Imm>; - - // TODO: Need v2f64, v4f32 - - def r64: ILRegInst<R64C, s16imm_i64, immSExt16>; - def r32: ILRegInst<R32C, s16imm_i32, immSExt16>; - def f32: ILRegInst<R32FP, s16imm_f32, fpimmSExt16>; - def f64: ILRegInst<R64FP, s16imm_f64, fpimmSExt16>; -} - -defm IL : ImmediateLoad; - -class ILHUInst<dag OOL, dag IOL, list<dag> pattern>: - RI16Form<0b010000010, OOL, IOL, "ilhu\t$rT, $val", - ImmLoad, pattern>; - -class ILHUVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: - ILHUInst<(outs VECREG:$rT), (ins immtype:$val), - [(set (vectype VECREG:$rT), (vectype xform:$val))]>; - -class ILHURegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: - ILHUInst<(outs rclass:$rT), (ins immtype:$val), - [(set rclass:$rT, xform:$val)]>; - -multiclass ImmLoadHalfwordUpper -{ - def v2i64: ILHUVecInst<v2i64, u16imm_i64, immILHUvec_i64>; - def v4i32: ILHUVecInst<v4i32, u16imm_i32, immILHUvec>; - - def r64: ILHURegInst<R64C, u16imm_i64, hi16>; - def r32: ILHURegInst<R32C, u16imm_i32, hi16>; - - // Loads the high portion of an address - def hi: ILHURegInst<R32C, symbolHi, hi16>; - - // Used in custom lowering constant SFP loads: - def f32: ILHURegInst<R32FP, f16imm, hi16_f32>; -} - -defm ILHU : ImmLoadHalfwordUpper; - -// Immediate load address (can also be used to load 18-bit unsigned constants, -// see the zext 16->32 pattern) - -class ILAInst<dag OOL, dag IOL, list<dag> pattern>: - RI18Form<0b1000010, OOL, IOL, "ila\t$rT, $val", - LoadNOP, pattern>; - -class ILAVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: - ILAInst<(outs VECREG:$rT), (ins immtype:$val), - [(set (vectype VECREG:$rT), (vectype xform:$val))]>; - -class ILARegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: - ILAInst<(outs rclass:$rT), (ins immtype:$val), - [(set rclass:$rT, xform:$val)]>; - -multiclass ImmLoadAddress -{ - def v2i64: ILAVecInst<v2i64, u18imm, v2i64Uns18Imm>; - def v4i32: ILAVecInst<v4i32, u18imm, v4i32Uns18Imm>; - - def r64: ILARegInst<R64C, u18imm_i64, imm18>; - def r32: ILARegInst<R32C, u18imm, imm18>; - def f32: ILARegInst<R32FP, f18imm, fpimm18>; - def f64: ILARegInst<R64FP, f18imm_f64, fpimm18>; - - def hi: ILARegInst<R32C, symbolHi, imm18>; - def lo: ILARegInst<R32C, symbolLo, imm18>; - - def lsa: ILAInst<(outs R32C:$rT), (ins symbolLSA:$val), - [(set R32C:$rT, imm18:$val)]>; -} - -defm ILA : ImmLoadAddress; - -// Immediate OR, Halfword Lower: The "other" part of loading large constants -// into 32-bit registers. See the anonymous pattern Pat<(i32 imm:$imm), ...> -// Note that these are really two operand instructions, but they're encoded -// as three operands with the first two arguments tied-to each other. - -class IOHLInst<dag OOL, dag IOL, list<dag> pattern>: - RI16Form<0b100000110, OOL, IOL, "iohl\t$rT, $val", - ImmLoad, pattern>, - RegConstraint<"$rS = $rT">, - NoEncode<"$rS">; - -class IOHLVecInst<ValueType vectype, Operand immtype /* , PatLeaf xform */>: - IOHLInst<(outs VECREG:$rT), (ins VECREG:$rS, immtype:$val), - [/* no pattern */]>; - -class IOHLRegInst<RegisterClass rclass, Operand immtype /* , PatLeaf xform */>: - IOHLInst<(outs rclass:$rT), (ins rclass:$rS, immtype:$val), - [/* no pattern */]>; - -multiclass ImmOrHalfwordLower -{ - def v2i64: IOHLVecInst<v2i64, u16imm_i64>; - def v4i32: IOHLVecInst<v4i32, u16imm_i32>; - - def r32: IOHLRegInst<R32C, i32imm>; - def f32: IOHLRegInst<R32FP, f32imm>; - - def lo: IOHLRegInst<R32C, symbolLo>; -} - -defm IOHL: ImmOrHalfwordLower; - -// Form select mask for bytes using immediate, used in conjunction with the -// SELB instruction: - -class FSMBIVec<ValueType vectype>: - RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), - "fsmbi\t$rT, $val", - SelectOp, - [(set (vectype VECREG:$rT), (SPUselmask (i16 immU16:$val)))]>; - -multiclass FormSelectMaskBytesImm -{ - def v16i8: FSMBIVec<v16i8>; - def v8i16: FSMBIVec<v8i16>; - def v4i32: FSMBIVec<v4i32>; - def v2i64: FSMBIVec<v2i64>; -} - -defm FSMBI : FormSelectMaskBytesImm; - -// fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits -class FSMBInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm_1<0b01101101100, OOL, IOL, "fsmb\t$rT, $rA", SelectOp, - pattern>; - -class FSMBRegInst<RegisterClass rclass, ValueType vectype>: - FSMBInst<(outs VECREG:$rT), (ins rclass:$rA), - [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; - -class FSMBVecInst<ValueType vectype>: - FSMBInst<(outs VECREG:$rT), (ins VECREG:$rA), - [(set (vectype VECREG:$rT), - (SPUselmask (vectype VECREG:$rA)))]>; - -multiclass FormSelectMaskBits { - def v16i8_r16: FSMBRegInst<R16C, v16i8>; - def v16i8: FSMBVecInst<v16i8>; -} - -defm FSMB: FormSelectMaskBits; - -// fsmh: Form select mask for halfwords. N.B., Input operand, $rA, is -// only 8-bits wide (even though it's input as 16-bits here) - -class FSMHInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm_1<0b10101101100, OOL, IOL, "fsmh\t$rT, $rA", SelectOp, - pattern>; - -class FSMHRegInst<RegisterClass rclass, ValueType vectype>: - FSMHInst<(outs VECREG:$rT), (ins rclass:$rA), - [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; - -class FSMHVecInst<ValueType vectype>: - FSMHInst<(outs VECREG:$rT), (ins VECREG:$rA), - [(set (vectype VECREG:$rT), - (SPUselmask (vectype VECREG:$rA)))]>; - -multiclass FormSelectMaskHalfword { - def v8i16_r16: FSMHRegInst<R16C, v8i16>; - def v8i16: FSMHVecInst<v8i16>; -} - -defm FSMH: FormSelectMaskHalfword; - -// fsm: Form select mask for words. Like the other fsm* instructions, -// only the lower 4 bits of $rA are significant. - -class FSMInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm_1<0b00101101100, OOL, IOL, "fsm\t$rT, $rA", SelectOp, - pattern>; - -class FSMRegInst<ValueType vectype, RegisterClass rclass>: - FSMInst<(outs VECREG:$rT), (ins rclass:$rA), - [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; - -class FSMVecInst<ValueType vectype>: - FSMInst<(outs VECREG:$rT), (ins VECREG:$rA), - [(set (vectype VECREG:$rT), (SPUselmask (vectype VECREG:$rA)))]>; - -multiclass FormSelectMaskWord { - def v4i32: FSMVecInst<v4i32>; - - def r32 : FSMRegInst<v4i32, R32C>; - def r16 : FSMRegInst<v4i32, R16C>; -} - -defm FSM : FormSelectMaskWord; - -// Special case when used for i64 math operations -multiclass FormSelectMaskWord64 { - def r32 : FSMRegInst<v2i64, R32C>; - def r16 : FSMRegInst<v2i64, R16C>; -} - -defm FSM64 : FormSelectMaskWord64; - -//===----------------------------------------------------------------------===// -// Integer and Logical Operations: -//===----------------------------------------------------------------------===// - -def AHv8i16: - RRForm<0b00010011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "ah\t$rT, $rA, $rB", IntegerOp, - [(set (v8i16 VECREG:$rT), (int_spu_si_ah VECREG:$rA, VECREG:$rB))]>; - -def : Pat<(add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), - (AHv8i16 VECREG:$rA, VECREG:$rB)>; - -def AHr16: - RRForm<0b00010011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - "ah\t$rT, $rA, $rB", IntegerOp, - [(set R16C:$rT, (add R16C:$rA, R16C:$rB))]>; - -def AHIvec: - RI10Form<0b10111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - "ahi\t$rT, $rA, $val", IntegerOp, - [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA), - v8i16SExt10Imm:$val))]>; - -def AHIr16: - RI10Form<0b10111000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), - "ahi\t$rT, $rA, $val", IntegerOp, - [(set R16C:$rT, (add R16C:$rA, i16ImmSExt10:$val))]>; - -// v4i32, i32 add instruction: - -class AInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b00000011000, OOL, IOL, - "a\t$rT, $rA, $rB", IntegerOp, - pattern>; - -class AVecInst<ValueType vectype>: - AInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), - (vectype VECREG:$rB)))]>; - -class ARegInst<RegisterClass rclass>: - AInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), - [(set rclass:$rT, (add rclass:$rA, rclass:$rB))]>; - -multiclass AddInstruction { - def v4i32: AVecInst<v4i32>; - def v16i8: AVecInst<v16i8>; - def r32: ARegInst<R32C>; -} - -defm A : AddInstruction; - -class AIInst<dag OOL, dag IOL, list<dag> pattern>: - RI10Form<0b00111000, OOL, IOL, - "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))]>; - -class AIFPVecInst<ValueType vectype, PatLeaf immpred>: - AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - [/* 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))]>; - -// 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 */]>; - -multiclass AddImmediate { - def v4i32: AIVecInst<v4i32, v4i32SExt10Imm>; - - def r32: AIRegInst<R32C, i32ImmSExt10>; - - def v4f32: AIFPVecInst<v4f32, v4i32SExt10Imm>; - def f32: AIFPInst<R32FP, i32ImmSExt10>; -} - -defm AI : AddImmediate; - -def SFHvec: - RRForm<0b00010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "sfh\t$rT, $rA, $rB", IntegerOp, - [(set (v8i16 VECREG:$rT), (sub (v8i16 VECREG:$rA), - (v8i16 VECREG:$rB)))]>; - -def SFHr16: - RRForm<0b00010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - "sfh\t$rT, $rA, $rB", IntegerOp, - [(set R16C:$rT, (sub R16C:$rB, R16C:$rA))]>; - -def SFHIvec: - RI10Form<0b10110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - "sfhi\t$rT, $rA, $val", IntegerOp, - [(set (v8i16 VECREG:$rT), (sub v8i16SExt10Imm:$val, - (v8i16 VECREG:$rA)))]>; - -def SFHIr16 : RI10Form<0b10110000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), - "sfhi\t$rT, $rA, $val", IntegerOp, - [(set R16C:$rT, (sub i16ImmSExt10:$val, R16C:$rA))]>; - -def SFvec : RRForm<0b00000010000, (outs VECREG:$rT), - (ins VECREG:$rA, VECREG:$rB), - "sf\t$rT, $rA, $rB", IntegerOp, - [(set (v4i32 VECREG:$rT), (sub (v4i32 VECREG:$rB), (v4i32 VECREG:$rA)))]>; - - -def SFr32 : RRForm<0b00000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - "sf\t$rT, $rA, $rB", IntegerOp, - [(set R32C:$rT, (sub R32C:$rB, R32C:$rA))]>; - -def SFIvec: - RI10Form<0b00110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - "sfi\t$rT, $rA, $val", IntegerOp, - [(set (v4i32 VECREG:$rT), (sub v4i32SExt10Imm:$val, - (v4i32 VECREG:$rA)))]>; - -def SFIr32 : RI10Form<0b00110000, (outs R32C:$rT), - (ins R32C:$rA, s10imm_i32:$val), - "sfi\t$rT, $rA, $val", IntegerOp, - [(set R32C:$rT, (sub i32ImmSExt10:$val, R32C:$rA))]>; - -// ADDX: only available in vector form, doesn't match a pattern. -class ADDXInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b00000010110, OOL, IOL, - "addx\t$rT, $rA, $rB", - IntegerOp, pattern>; - -class ADDXVecInst<ValueType vectype>: - ADDXInst<(outs VECREG:$rT), - (ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry), - [/* no pattern */]>, - RegConstraint<"$rCarry = $rT">, - NoEncode<"$rCarry">; - -class ADDXRegInst<RegisterClass rclass>: - ADDXInst<(outs rclass:$rT), - (ins rclass:$rA, rclass:$rB, rclass:$rCarry), - [/* no pattern */]>, - RegConstraint<"$rCarry = $rT">, - NoEncode<"$rCarry">; - -multiclass AddExtended { - def v2i64 : ADDXVecInst<v2i64>; - def v4i32 : ADDXVecInst<v4i32>; - def r64 : ADDXRegInst<R64C>; - def r32 : ADDXRegInst<R32C>; -} - -defm ADDX : AddExtended; - -// CG: Generate carry for add -class CGInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b01000011000, OOL, IOL, - "cg\t$rT, $rA, $rB", - IntegerOp, pattern>; - -class CGVecInst<ValueType vectype>: - CGInst<(outs VECREG:$rT), - (ins VECREG:$rA, VECREG:$rB), - [/* no pattern */]>; - -class CGRegInst<RegisterClass rclass>: - CGInst<(outs rclass:$rT), - (ins rclass:$rA, rclass:$rB), - [/* no pattern */]>; - -multiclass CarryGenerate { - def v2i64 : CGVecInst<v2i64>; - def v4i32 : CGVecInst<v4i32>; - def r64 : CGRegInst<R64C>; - def r32 : CGRegInst<R32C>; -} - -defm CG : CarryGenerate; - -// SFX: Subract from, extended. This is used in conjunction with BG to subtract -// with carry (borrow, in this case) -class SFXInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b10000010110, OOL, IOL, - "sfx\t$rT, $rA, $rB", - IntegerOp, pattern>; - -class SFXVecInst<ValueType vectype>: - SFXInst<(outs VECREG:$rT), - (ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry), - [/* no pattern */]>, - RegConstraint<"$rCarry = $rT">, - NoEncode<"$rCarry">; - -class SFXRegInst<RegisterClass rclass>: - SFXInst<(outs rclass:$rT), - (ins rclass:$rA, rclass:$rB, rclass:$rCarry), - [/* no pattern */]>, - RegConstraint<"$rCarry = $rT">, - NoEncode<"$rCarry">; - -multiclass SubtractExtended { - def v2i64 : SFXVecInst<v2i64>; - def v4i32 : SFXVecInst<v4i32>; - def r64 : SFXRegInst<R64C>; - def r32 : SFXRegInst<R32C>; -} - -defm SFX : SubtractExtended; - -// BG: only available in vector form, doesn't match a pattern. -class BGInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b01000010000, OOL, IOL, - "bg\t$rT, $rA, $rB", - IntegerOp, pattern>; - -class BGVecInst<ValueType vectype>: - BGInst<(outs VECREG:$rT), - (ins VECREG:$rA, VECREG:$rB), - [/* no pattern */]>; - -class BGRegInst<RegisterClass rclass>: - BGInst<(outs rclass:$rT), - (ins rclass:$rA, rclass:$rB), - [/* no pattern */]>; - -multiclass BorrowGenerate { - def v4i32 : BGVecInst<v4i32>; - def v2i64 : BGVecInst<v2i64>; - def r64 : BGRegInst<R64C>; - def r32 : BGRegInst<R32C>; -} - -defm BG : BorrowGenerate; - -// BGX: Borrow generate, extended. -def BGXvec: - RRForm<0b11000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, - VECREG:$rCarry), - "bgx\t$rT, $rA, $rB", IntegerOp, - []>, - RegConstraint<"$rCarry = $rT">, - NoEncode<"$rCarry">; - -// Halfword multiply variants: -// N.B: These can be used to build up larger quantities (16x16 -> 32) - -def MPYv8i16: - RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "mpy\t$rT, $rA, $rB", IntegerMulDiv, - [/* no pattern */]>; - -def MPYr16: - RRForm<0b00100011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - "mpy\t$rT, $rA, $rB", IntegerMulDiv, - [(set R16C:$rT, (mul R16C:$rA, R16C:$rB))]>; - -// Unsigned 16-bit multiply: - -class MPYUInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b00110011110, OOL, IOL, - "mpyu\t$rT, $rA, $rB", IntegerMulDiv, - pattern>; - -def MPYUv4i32: - MPYUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - [/* no pattern */]>; - -def MPYUr16: - MPYUInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB), - [(set R32C:$rT, (mul (zext R16C:$rA), (zext R16C:$rB)))]>; - -def MPYUr32: - MPYUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - [/* no pattern */]>; - -// mpyi: multiply 16 x s10imm -> 32 result. - -class MPYIInst<dag OOL, dag IOL, list<dag> pattern>: - RI10Form<0b00101110, OOL, IOL, - "mpyi\t$rT, $rA, $val", IntegerMulDiv, - pattern>; - -def MPYIvec: - MPYIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - [(set (v8i16 VECREG:$rT), - (mul (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; - -def MPYIr16: - MPYIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), - [(set R16C:$rT, (mul R16C:$rA, i16ImmSExt10:$val))]>; - -// mpyui: same issues as other multiplies, plus, this doesn't match a -// pattern... but may be used during target DAG selection or lowering - -class MPYUIInst<dag OOL, dag IOL, list<dag> pattern>: - RI10Form<0b10101110, OOL, IOL, - "mpyui\t$rT, $rA, $val", IntegerMulDiv, - pattern>; - -def MPYUIvec: - MPYUIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - []>; - -def MPYUIr16: - MPYUIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), - []>; - -// mpya: 16 x 16 + 16 -> 32 bit result -class MPYAInst<dag OOL, dag IOL, list<dag> pattern>: - RRRForm<0b0011, OOL, IOL, - "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, - pattern>; - -def MPYAv4i32: - MPYAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - [(set (v4i32 VECREG:$rT), - (add (v4i32 (bitconvert (mul (v8i16 VECREG:$rA), - (v8i16 VECREG:$rB)))), - (v4i32 VECREG:$rC)))]>; - -def MPYAr32: - MPYAInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), - [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)), - R32C:$rC))]>; - -def MPYAr32_sext: - MPYAInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), - [(set R32C:$rT, (add (mul (sext R16C:$rA), (sext R16C:$rB)), - R32C:$rC))]>; - -def MPYAr32_sextinreg: - MPYAInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC), - [(set R32C:$rT, (add (mul (sext_inreg R32C:$rA, i16), - (sext_inreg R32C:$rB, i16)), - R32C:$rC))]>; - -// mpyh: multiply high, used to synthesize 32-bit multiplies -class MPYHInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm<0b10100011110, OOL, IOL, - "mpyh\t$rT, $rA, $rB", IntegerMulDiv, - pattern>; - -def MPYHv4i32: - MPYHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - [/* no pattern */]>; - -def MPYHr32: - MPYHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - [/* no pattern */]>; - -// mpys: multiply high and shift right (returns the top half of -// a 16-bit multiply, sign extended to 32 bits.) - -class MPYSInst<dag OOL, dag IOL>: - RRForm<0b11100011110, OOL, IOL, - "mpys\t$rT, $rA, $rB", IntegerMulDiv, - [/* no pattern */]>; - -def MPYSv4i32: - MPYSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; - -def MPYSr16: - MPYSInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB)>; - -// mpyhh: multiply high-high (returns the 32-bit result from multiplying -// the top 16 bits of the $rA, $rB) - -class MPYHHInst<dag OOL, dag IOL>: - RRForm<0b01100011110, OOL, IOL, - "mpyhh\t$rT, $rA, $rB", IntegerMulDiv, - [/* no pattern */]>; - -def MPYHHv8i16: - MPYHHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; - -def MPYHHr32: - MPYHHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; - -// mpyhha: Multiply high-high, add to $rT: - -class MPYHHAInst<dag OOL, dag IOL>: - RRForm<0b01100010110, OOL, IOL, - "mpyhha\t$rT, $rA, $rB", IntegerMulDiv, - [/* no pattern */]>; - -def MPYHHAvec: - MPYHHAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; - -def MPYHHAr32: - MPYHHAInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; - -// 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 MPYHHUv4i32: - MPYHHUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; - -def MPYHHUr32: - MPYHHUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; - -// mpyhhau: Multiply high-high, unsigned - -class MPYHHAUInst<dag OOL, dag IOL>: - RRForm<0b01110010110, OOL, IOL, - "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv, - [/* no pattern */]>; - -def MPYHHAUvec: - MPYHHAUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; - -def MPYHHAUr32: - MPYHHAUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; - -//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ -// clz: Count leading zeroes -//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ -class CLZInst<dag OOL, dag IOL, list<dag> pattern>: - RRForm_1<0b10100101010, OOL, IOL, "clz\t$rT, $rA", - IntegerOp, pattern>; - -class CLZRegInst<RegisterClass rclass>: - CLZInst<(outs rclass:$rT), (ins rclass:$rA), - [(set rclass:$rT, (ctlz rclass:$rA))]>; - -class CLZVecInst<ValueType vectype>: - CLZInst<(outs VECREG:$rT), (ins VECREG:$rA), - [(set (vectype VECREG:$rT), (ctlz (vectype VECREG:$rA)))]>; - -multiclass CountLeadingZeroes { - def v4i32 : CLZVecInst<v4i32>; - def r32 : CLZRegInst<R32C>; -} - -defm CLZ : CountLeadingZeroes; - -// cntb: Count ones in bytes (aka "p |