public static void Ldc(EmitterContext context) { OpCodeLdc op = (OpCodeLdc)context.CurrOp; if (op.Size > IntegerSize.B64) { context.Config.GpuAccessor.Log($"Invalid LDC size: {op.Size}."); } bool isSmallInt = op.Size < IntegerSize.B32; int count = op.Size == IntegerSize.B64 ? 2 : 1; Operand slot = Const(op.Slot); Operand srcA = GetSrcA(context); if (op.IndexMode == CbIndexMode.Is || op.IndexMode == CbIndexMode.Isl) { slot = context.IAdd(slot, context.BitfieldExtractU32(srcA, Const(16), Const(16))); srcA = context.BitwiseAnd(srcA, Const(0xffff)); } Operand addr = context.IAdd(srcA, Const(op.Offset)); Operand wordOffset = context.ShiftRightU32(addr, Const(2)); Operand bitOffset = GetBitOffset(context, addr); for (int index = 0; index < count; index++) { Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); if (rd.IsRZ) { break; } Operand offset = context.IAdd(wordOffset, Const(index)); Operand value = context.LoadConstant(slot, offset); if (isSmallInt) { value = ExtractSmallInt(context, op.Size, bitOffset, value); } context.Copy(Register(rd), value); } }
public static void Ldc(EmitterContext context) { OpCodeLdc op = (OpCodeLdc)context.CurrOp; if (op.Size > IntegerSize.B64) { // TODO: Warning. } bool isSmallInt = op.Size < IntegerSize.B32; int count = op.Size == IntegerSize.B64 ? 2 : 1; Operand baseOffset = context.Copy(GetSrcA(context)); for (int index = 0; index < count; index++) { Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); if (rd.IsRZ) { break; } Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4)); Operand value = context.LoadConstant(Const(op.Slot), offset); if (isSmallInt) { Operand shift = context.BitwiseAnd(baseOffset, Const(3)); value = context.ShiftRightU32(value, shift); switch (op.Size) { case IntegerSize.U8: value = ZeroExtendTo32(context, value, 8); break; case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break; case IntegerSize.S8: value = SignExtendTo32(context, value, 8); break; case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break; } } context.Copy(Register(rd), value); } }
public static void Ldc(EmitterContext context) { OpCodeLdc op = (OpCodeLdc)context.CurrOp; if (op.Size > IntegerSize.B64) { context.Config.PrintLog($"Invalid LDC size: {op.Size}."); } bool isSmallInt = op.Size < IntegerSize.B32; int count = op.Size == IntegerSize.B64 ? 2 : 1; Operand wordOffset = context.ShiftRightU32(GetSrcA(context), Const(2)); wordOffset = context.IAdd(wordOffset, Const(op.Offset)); Operand bitOffset = GetBitOffset(context, GetSrcA(context)); for (int index = 0; index < count; index++) { Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr); if (rd.IsRZ) { break; } Operand offset = context.IAdd(wordOffset, Const(index)); Operand value = context.LoadConstant(Const(op.Slot), offset); if (isSmallInt) { value = ExtractSmallInt(context, op.Size, bitOffset, value); } context.Copy(Register(rd), value); } }