private static void EmitLdg( EmitterContext context, LsSize size, int ra, int rd, int offset, bool extended) { bool isSmallInt = size < LsSize.B32; int count = GetVectorCount(size); (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, new Register(ra, RegisterType.Gpr), extended, offset); Operand bitOffset = GetBitOffset(context, addrLow); for (int index = 0; index < count; index++) { Register dest = new Register(rd + index, RegisterType.Gpr); if (dest.IsRZ) { break; } Operand value = context.LoadGlobal(context.IAdd(addrLow, Const(index * 4)), addrHigh); if (isSmallInt) { value = ExtractSmallInt(context, size, bitOffset, value); } context.Copy(Register(dest), value); } }
private static int GetVectorCount(LsSize size) { switch (size) { case LsSize.B64: return(2); case LsSize.B128: case LsSize.UB128: return(4); } return(1); }
private static Operand ExtractSmallInt( EmitterContext context, LsSize size, Operand bitOffset, Operand value) { value = context.ShiftRightU32(value, bitOffset); switch (size) { case LsSize.U8: value = ZeroExtendTo32(context, value, 8); break; case LsSize.U16: value = ZeroExtendTo32(context, value, 16); break; case LsSize.S8: value = SignExtendTo32(context, value, 8); break; case LsSize.S16: value = SignExtendTo32(context, value, 16); break; } return(value); }
private static Operand InsertSmallInt( EmitterContext context, LsSize size, Operand bitOffset, Operand word, Operand value) { switch (size) { case LsSize.U8: case LsSize.S8: value = context.BitwiseAnd(value, Const(0xff)); value = context.BitfieldInsert(word, value, bitOffset, Const(8)); break; case LsSize.U16: case LsSize.S16: value = context.BitwiseAnd(value, Const(0xffff)); value = context.BitfieldInsert(word, value, bitOffset, Const(16)); break; } return(value); }