From: Tom Stellard Date: Tue, 31 Jul 2012 20:05:54 +0000 (+0000) Subject: radeon/llvm: Add pseudo-support for 64-bit immediate types on SI X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a488fdd3d97a6e9fa1ff8b8d22193551391170d3;p=mesa.git radeon/llvm: Add pseudo-support for 64-bit immediate types on SI SI does not support 64-bit immediates natively, but llvm will generate i64 immediates when indexing loads and stores (since SI has 64-bit pointers). The i64 indices will always be small enough to fit into 32-bits (i.e. the high 32 bits will always be all zeros), so we can treat these index values as 32-bits. --- diff --git a/src/gallium/drivers/radeon/SIInstrInfo.td b/src/gallium/drivers/radeon/SIInstrInfo.td index 36496f0cc73..81df55d135e 100644 --- a/src/gallium/drivers/radeon/SIInstrInfo.td +++ b/src/gallium/drivers/radeon/SIInstrInfo.td @@ -71,6 +71,11 @@ def IMM12bit : ImmLeaf < [{return (int16_t)Imm >= 0 && (int16_t)Imm <= 0xfff;}] >; +def IMM32bitIn64bit : ImmLeaf < + i64, + [{return isInt<32>(Imm);}] +>; + class GPR4Align : Operand { let EncoderMethod = "GPR4AlignEncode"; let MIOperandInfo = (ops rc:$reg); @@ -85,6 +90,12 @@ def i32Literal : Operand { let EncoderMethod = "i32LiteralEncode"; } +// i64Literal uses the same encoder method as i32 literal, because an +// i64Literal is really a i32 literal with the top 32-bits all set to zero. +def i64Literal : Operand { + let EncoderMethod = "i32LiteralEncode"; +} + def SMRDmemrr : Operand { let MIOperandInfo = (ops SReg_64, SReg_32); let EncoderMethod = "GPR2AlignEncode"; diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td index 42bb449f2ee..94748b67259 100644 --- a/src/gallium/drivers/radeon/SIInstructions.td +++ b/src/gallium/drivers/radeon/SIInstructions.td @@ -884,6 +884,18 @@ def S_MOV_IMM_I32 : SOP1 < [(set SReg_32:$dst, (imm:$src0))] >; +// i64 immediates aren't really supported in hardware, but LLVM will use the i64 +// type for indices on load and store instructions. The pattern for +// S_MOV_IMM_I64 will only match i64 immediates that can fit into 32-bits, +// which the hardware can handle. +def S_MOV_IMM_I64 : SOP1 < + 0x3, + (outs SReg_64:$dst), + (ins i64Literal:$src0), + "S_MOV_IMM_I64 $dst, $src0", + [(set SReg_64:$dst, (IMM32bitIn64bit:$src0))] +>; + let isCodeGenOnly = 1, isPseudo = 1 in { def SET_M0 : InstSI <