diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/StructMoves.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/StructMoves.c')
-rw-r--r-- | compiler_and_linker/unsorted/StructMoves.c | 792 |
1 files changed, 0 insertions, 792 deletions
diff --git a/compiler_and_linker/unsorted/StructMoves.c b/compiler_and_linker/unsorted/StructMoves.c deleted file mode 100644 index 7c28b88..0000000 --- a/compiler_and_linker/unsorted/StructMoves.c +++ /dev/null @@ -1,792 +0,0 @@ -#include "compiler/StructMoves.h" -#include "compiler/CError.h" -#include "compiler/CParser.h" -#include "compiler/CodeGen.h" -#include "compiler/Operands.h" -#include "compiler/PCode.h" -#include "compiler/PCodeUtilities.h" -#include "compiler/Registers.h" - -void make_addressable(Operand *opnd, SInt32 offset, int unusedArg) { - int reg; - - if (opnd->optype == OpndType_IndirectSymbol) - coerce_to_addressable(opnd); - - if (opnd->optype != OpndType_IndirectGPR_ImmOffset || (opnd->immOffset + offset) > 0x7FFF) { - reg = used_virtual_registers[RegClass_GPR]++; - load_address(reg, opnd); - opnd->optype = OpndType_IndirectGPR_ImmOffset; - opnd->reg = reg; - opnd->object = NULL; - opnd->immOffset = 0; - } -} - -static void load_displaced_address(Operand *opnd, SInt32 offset) { - int reg; - - reg = used_virtual_registers[RegClass_GPR]++; - if (opnd->optype == OpndType_IndirectSymbol) - coerce_to_addressable(opnd); - - if (opnd->optype == OpndType_IndirectGPR_ImmOffset) { - offset += opnd->immOffset; - if (!FITS_IN_SHORT(offset)) { - add_immediate(reg, opnd->reg, opnd->object, opnd->immOffset); - emitpcode(PC_ADDI, reg, reg, 0, offset - opnd->immOffset); - } else { - add_immediate(reg, opnd->reg, opnd->object, offset); - } - } else if (opnd->optype == OpndType_IndirectGPR_Indexed) { - emitpcode(PC_ADD, reg, opnd->reg, opnd->regOffset); - emitpcode(PC_ADDI, reg, reg, 0, offset); - } else { - CError_FATAL(80); - } - - opnd->optype = OpndType_IndirectGPR_ImmOffset; - opnd->reg = reg; - opnd->object = NULL; - opnd->immOffset = 0; -} - -static void move_block_via_load_store(Operand *dst, Operand *src, SInt32 len, SInt32 align) { - SInt32 step; - SInt32 pos; - int floatReg; - int reg; - - if (src->optype == OpndType_IndirectSymbol) - coerce_to_addressable(src); - if (dst->optype == OpndType_IndirectSymbol) - coerce_to_addressable(dst); - - if (len == 8) { - floatReg = used_virtual_registers[RegClass_FPR]++; - if (src->optype == OpndType_IndirectGPR_ImmOffset) { - load_store_register(PC_LFD, floatReg, src->reg, src->object, src->immOffset); - setpcodeflags(src->flags); - } else if (src->optype == OpndType_IndirectGPR_Indexed) { - emitpcode(PC_LFDX, floatReg, src->reg, src->regOffset); - setpcodeflags(src->flags); - } else { - CError_FATAL(145); - } - - if (dst->optype == OpndType_IndirectGPR_ImmOffset) { - load_store_register(PC_STFD, floatReg, dst->reg, dst->object, dst->immOffset); - setpcodeflags(dst->flags); - } else if (dst->optype == OpndType_IndirectGPR_Indexed) { - emitpcode(PC_STFDX, floatReg, dst->reg, dst->regOffset); - setpcodeflags(dst->flags); - } else { - CError_FATAL(157); - } - - return; - } - - if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) { - SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align; - step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2; - } else { - step = ((UInt32) len > 4) ? 4 : ((UInt32) len <= 2) ? len : 2; - } - - if (step != len) { - if (dst->optype == OpndType_IndirectGPR_Indexed) - make_addressable(dst, len, 0); - if (src->optype == OpndType_IndirectGPR_Indexed) - make_addressable(src, len, 0); - } - - for (pos = 0; len != 0; len -= step, pos += step) { - reg = used_virtual_registers[RegClass_GPR]++; - if (src->optype == OpndType_IndirectGPR_ImmOffset) { - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg, - src->reg, - src->object, - src->immOffset + pos - ); - setpcodeflags(src->flags); - } else if (src->optype == OpndType_IndirectGPR_Indexed) { - emitpcode( - (step == 1) ? PC_LBZX : (step == 2) ? PC_LHZX : PC_LWZX, - reg, - src->reg, - src->regOffset - ); - setpcodeflags(src->flags); - } else { - CError_FATAL(183); - } - - if (dst->optype == OpndType_IndirectGPR_ImmOffset) { - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg, - dst->reg, - dst->object, - dst->immOffset + pos - ); - setpcodeflags(dst->flags); - } else if (dst->optype == OpndType_IndirectGPR_Indexed) { - emitpcode( - (step == 1) ? PC_STBX : (step == 2) ? PC_STHX : PC_STWX, - reg, - dst->reg, - dst->regOffset - ); - setpcodeflags(dst->flags); - } else { - CError_FATAL(195); - } - } -} - -static void move_block_via_load_store_sequence(Operand *dst, Operand *src, SInt32 len, SInt32 align) { - SInt32 pos; - int i; - SInt32 step; - - pos = 0; - make_addressable(dst, len, 0); - make_addressable(src, len, 0); - - if ((align % 8) == 0) { - while (len >= 16) { - int reg1 = used_virtual_registers[RegClass_FPR]++; - int reg2 = used_virtual_registers[RegClass_FPR]++; - load_store_register(PC_LFD, reg1, src->reg, src->object, src->immOffset + pos); - setpcodeflags(src->flags); - load_store_register(PC_LFD, reg2, src->reg, src->object, src->immOffset + pos + 8); - setpcodeflags(src->flags); - - load_store_register(PC_STFD, reg1, dst->reg, dst->object, dst->immOffset + pos); - setpcodeflags(dst->flags); - load_store_register(PC_STFD, reg2, dst->reg, dst->object, dst->immOffset + pos + 8); - setpcodeflags(dst->flags); - - pos += 16; - len -= 16; - } - } - - while (len >= 8) { - if ((align % 8) == 0) { - int reg = used_virtual_registers[RegClass_FPR]++; - - load_store_register(PC_LFD, reg, src->reg, src->object, src->immOffset + pos); - setpcodeflags(src->flags); - - load_store_register(PC_STFD, reg, dst->reg, dst->object, dst->immOffset + pos); - setpcodeflags(dst->flags); - - pos += 8; - len -= 8; - } else { - if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) { - SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align; - step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp > 2) ? 2 : 1; - } else { - step = 4; - } - - for (i = 0; i < 8; i += (step * 2)) { - int reg1 = used_virtual_registers[RegClass_GPR]++; - int reg2 = used_virtual_registers[RegClass_GPR]++; - - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg1, - src->reg, - src->object, - src->immOffset + pos - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg2, - src->reg, - src->object, - src->immOffset + pos + step - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg1, - dst->reg, - dst->object, - dst->immOffset + pos - ); - setpcodeflags(dst->flags); - - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg2, - dst->reg, - dst->object, - dst->immOffset + pos + step - ); - setpcodeflags(dst->flags); - - pos += (step * 2); - len -= (step * 2); - } - } - } - - while (len) { - int reg; - - if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) { - SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align; - step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2; - } else { - step = ((UInt32) len > 4) ? 4 : ((UInt32) len <= 2) ? len : 2; - } - - reg = used_virtual_registers[RegClass_GPR]++; - - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg, - src->reg, - src->object, - src->immOffset + pos - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg, - dst->reg, - dst->object, - dst->immOffset + pos - ); - setpcodeflags(dst->flags); - - len -= step; - pos += step; - } -} - -static void move_block_via_inline_loop(Operand *dst, Operand *src, SInt32 len, SInt32 align) { - PCodeLabel *label; // r25 - SInt32 pos; // r25 - SInt32 step; // r24 - int reg1; // r22 - int reg2; // r23 - SInt32 remainder; // r23 - - label = makepclabel(); - - if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) { - SInt32 tmp = (align == 0) ? 1 : (align > len) ? len : align; - step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2; - } else { - step = 4; - } - - load_displaced_address(dst, -step); - load_displaced_address(src, -step); - - CError_ASSERT(377, (len / step) != 0); - - reg1 = used_virtual_registers[RegClass_GPR]++; - load_immediate(reg1, len / (step * 2)); - emitpcode(PC_MTCTR, reg1); - branch_label(label); - - reg1 = used_virtual_registers[RegClass_GPR]++; - reg2 = used_virtual_registers[RegClass_GPR]++; - - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg1, - src->reg, - NULL, - step - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_LBZU : (step == 2) ? PC_LHZU : PC_LWZU, - reg2, - src->reg, - NULL, - step * 2 - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg1, - dst->reg, - NULL, - step - ); - setpcodeflags(dst->flags); - - load_store_register( - (step == 1) ? PC_STBU : (step == 2) ? PC_STHU : PC_STWU, - reg2, - dst->reg, - NULL, - step * 2 - ); - setpcodeflags(dst->flags); - - branch_decrement_always(PC_BDNZ, label); - - for (remainder = len & 7, pos = step; remainder != 0; remainder -= step, pos += step) { - int reg; - - if (copts.misaligned_mem_access == 0 && (UInt32) align < 4) { - SInt32 tmp = (align == 0) ? 1 : (align > remainder) ? remainder : align; - step = ((UInt32) tmp > 4) ? 4 : ((UInt32) tmp <= 2) ? (UInt32) tmp : 2; - } else { - step = ((UInt32) remainder > 4) ? 4 : ((UInt32) remainder <= 2) ? remainder : 2; - } - - reg = used_virtual_registers[RegClass_GPR]++; - - load_store_register( - (step == 1) ? PC_LBZ : (step == 2) ? PC_LHZ : PC_LWZ, - reg, - src->reg, - NULL, - pos - ); - setpcodeflags(src->flags); - - load_store_register( - (step == 1) ? PC_STB : (step == 2) ? PC_STH : PC_STW, - reg, - dst->reg, - NULL, - pos - ); - setpcodeflags(dst->flags); - } -} - -void move_block(Operand *dst, Operand *src, SInt32 len, SInt32 align) { - Operand myDst; - - myDst = *dst; - - CError_ASSERT(447, myDst.optype >= OpndType_IndirectGPR_ImmOffset); - CError_ASSERT(449, src->optype >= OpndType_IndirectGPR_ImmOffset); - - if (len == 1 || len == 2 || len == 4) - move_block_via_load_store(&myDst, src, len, align); - else if (len == 8 && align == 8) - move_block_via_load_store(&myDst, src, len, align); - else if (len <= 16 || (copts.optimizesize == 0 && len <= 64)) - move_block_via_load_store_sequence(&myDst, src, len, align); - else - move_block_via_inline_loop(&myDst, src, len, align); -} - -static void load_word_of_small_struct(short dstReg, short srcReg, Operand *opnd, SInt32 offset, SInt32 len, SInt32 align) { - short tmpReg; - short extra = 0; - - switch (len) { - case 1: - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7); - setpcodeflags(opnd->flags); - break; - case 2: - case 3: - if (align > 1) { - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset); - extra += 2; - setpcodeflags(opnd->flags); - emitpcode(PC_RLWINM, dstReg, tmpReg, 16, 0, 15); - setpcodeflags(opnd->flags); - } else { - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7); - setpcodeflags(opnd->flags); - - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 1); - extra += 2; - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 16, 8, 15); - setpcodeflags(opnd->flags); - } - if (len == 3) { - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + extra); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 8, 16, 23); - setpcodeflags(opnd->flags); - } - break; - case 4: - if (align > 2) { - load_store_register(PC_LWZ, dstReg, srcReg, opnd->object, offset); - setpcodeflags(opnd->flags); - } else if (align > 1) { - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWINM, dstReg, tmpReg, 16, 0, 15); - setpcodeflags(opnd->flags); - - load_store_register(PC_LHZ, tmpReg, srcReg, opnd->object, offset + 2); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 0, 16, 31); - setpcodeflags(opnd->flags); - } else { - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWINM, dstReg, tmpReg, 24, 0, 7); - setpcodeflags(opnd->flags); - - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 1); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 16, 8, 15); - setpcodeflags(opnd->flags); - - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 2); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 8, 16, 23); - setpcodeflags(opnd->flags); - - load_store_register(PC_LBZ, tmpReg, srcReg, opnd->object, offset + 3); - setpcodeflags(opnd->flags); - emitpcode(PC_RLWIMI, dstReg, tmpReg, 0, 24, 31); - setpcodeflags(opnd->flags); - } - break; - } -} - -void load_small_block_into_reg(short dstReg, Operand *srcOpnd, Type *type, SInt32 align) { - short finalReg; - short tmpReg; - SInt32 absAddress; - - coerce_to_addressable(srcOpnd); - - if (srcOpnd->optype == OpndType_IndirectGPR_Indexed) { - CError_FATAL(557); - - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_address(tmpReg, srcOpnd); - srcOpnd->optype = OpndType_IndirectGPR_ImmOffset; - srcOpnd->reg = tmpReg; - srcOpnd->object = NULL; - srcOpnd->immOffset = 0; - } - - if (copts.misaligned_mem_access) - align = 4; - - switch (srcOpnd->optype) { - case OpndType_GPRPair: - return; - case OpndType_GPR: - return; - case OpndType_GPR_ImmOffset: - finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++; - add_immediate(finalReg, srcOpnd->reg, srcOpnd->object, srcOpnd->immOffset); - break; - case OpndType_GPR_Indexed: - finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_ADD, finalReg, srcOpnd->reg, srcOpnd->regOffset); - break; - case OpndType_Absolute: - finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++; - absAddress = srcOpnd->immediate; - if (FITS_IN_SHORT(absAddress)) { - emitpcode(PC_LI, finalReg, absAddress); - } else { - tmpReg = finalReg; - if (copts.optimizationlevel > 1 && absAddress) - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_LIS, tmpReg, 0, HIGH_PART(absAddress)); - if (absAddress) - emitpcode(PC_ADDI, finalReg, tmpReg, 0, LOW_PART(absAddress)); - } - break; - case OpndType_IndirectGPR_ImmOffset: - finalReg = dstReg ? dstReg : used_virtual_registers[RegClass_GPR]++; - load_word_of_small_struct(finalReg, srcOpnd->reg, srcOpnd, srcOpnd->immOffset, type->size, align); - break; - default: - CError_FATAL(606); - } - - srcOpnd->optype = OpndType_GPR; - srcOpnd->reg = finalReg; -} - -void load_small_block_into_reg_pair(short dstRegLo, short dstRegHi, Operand *srcOpnd, Type *type, SInt32 align) { - short finalRegLo; - short finalRegHi; - short tmpRegLo; - short tmpRegHi; - short tmpReg; - SInt32 absAddress; - - finalRegHi = -1; - coerce_to_addressable(srcOpnd); - - if (srcOpnd->optype == OpndType_IndirectGPR_Indexed) { - CError_FATAL(624); - - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_address(tmpReg, srcOpnd); - srcOpnd->optype = OpndType_IndirectGPR_ImmOffset; - srcOpnd->reg = tmpReg; - srcOpnd->object = NULL; - srcOpnd->immOffset = 0; - } - - if (copts.misaligned_mem_access) - align = 4; - - switch (srcOpnd->optype) { - case OpndType_GPRPair: - if (dstRegLo != 0 && dstRegHi == 0) - dstRegHi = used_virtual_registers[RegClass_GPR]++; - if (dstRegHi != 0 && dstRegLo == 0) - dstRegLo = used_virtual_registers[RegClass_GPR]++; - - if (srcOpnd->reg != dstRegLo || srcOpnd->regHi != dstRegHi) { - tmpRegLo = dstRegLo ? dstRegLo : srcOpnd->reg; - tmpRegHi = dstRegHi ? dstRegHi : srcOpnd->regHi; - - if (tmpRegLo != srcOpnd->reg) { - if (tmpRegLo == srcOpnd->regHi) { - CError_ASSERT(657, tmpRegLo != tmpRegHi); - emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi); - emitpcode(PC_MR, tmpRegLo, srcOpnd->reg); - } else { - emitpcode(PC_MR, tmpRegLo, srcOpnd->reg); - if (srcOpnd->regHi != tmpRegHi) - emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi); - } - } else if (tmpRegHi != srcOpnd->regHi) { - if (tmpRegHi == srcOpnd->reg) { - CError_ASSERT(671, tmpRegLo != tmpRegHi); - emitpcode(PC_MR, tmpRegLo, srcOpnd->reg); - emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi); - } else { - emitpcode(PC_MR, tmpRegHi, srcOpnd->regHi); - if (srcOpnd->reg != tmpRegLo) - emitpcode(PC_MR, tmpRegLo, srcOpnd->reg); - } - } - } - - finalRegLo = srcOpnd->reg; - finalRegHi = srcOpnd->regHi; - break; - case OpndType_GPR: - CError_FATAL(688); - break; - case OpndType_GPR_ImmOffset: - CError_FATAL(691); - break; - case OpndType_GPR_Indexed: - CError_FATAL(694); - break; - case OpndType_Absolute: - finalRegLo = dstRegLo ? dstRegLo : used_virtual_registers[RegClass_GPR]++; - absAddress = srcOpnd->immediate; - if (FITS_IN_SHORT(absAddress)) { - emitpcode(PC_LI, finalRegLo, absAddress); - } else { - tmpReg = finalRegLo; - if (copts.optimizationlevel > 1 && absAddress) - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_LIS, tmpReg, 0, HIGH_PART(absAddress)); - if (absAddress) - emitpcode(PC_ADDI, finalRegLo, tmpReg, 0, LOW_PART(absAddress)); - } - - finalRegHi = dstRegHi ? dstRegHi : used_virtual_registers[RegClass_GPR]++; - if (is_unsigned(type) || absAddress >= 0) - load_immediate(finalRegHi, 0); - else - load_immediate(finalRegHi, -1); - - break; - case OpndType_IndirectGPR_ImmOffset: - finalRegLo = dstRegLo ? dstRegLo : used_virtual_registers[RegClass_GPR]++; - finalRegHi = dstRegHi ? dstRegHi : used_virtual_registers[RegClass_GPR]++; - if (srcOpnd->reg == finalRegHi) { - if (srcOpnd->reg == finalRegLo) { - CError_FATAL(726); - } else { - load_word_of_small_struct( - finalRegLo, srcOpnd->reg, srcOpnd, - srcOpnd->immOffset + low_offset, type->size - 4, align); - load_word_of_small_struct( - finalRegHi, srcOpnd->reg, srcOpnd, - srcOpnd->immOffset + high_offset, 4, align); - } - } else { - load_word_of_small_struct( - finalRegHi, srcOpnd->reg, srcOpnd, - srcOpnd->immOffset + high_offset, 4, align); - load_word_of_small_struct( - finalRegLo, srcOpnd->reg, srcOpnd, - srcOpnd->immOffset + low_offset, type->size - 4, align); - } - break; - default: - CError_FATAL(737); - } - - if (finalRegHi == -1) { - CError_FATAL(741); - } else { - srcOpnd->optype = OpndType_GPRPair; - srcOpnd->reg = finalRegLo; - srcOpnd->regHi = finalRegHi; - } -} - -static void store_word_of_small_struct(short srcReg, short dstReg, Operand *opnd, SInt32 offset, SInt32 len, SInt32 align) { - short tmpReg; - short extra = 0; - - switch (len) { - case 1: - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset); - setpcodeflags(opnd->flags); - break; - case 2: - case 3: - if (align > 1) { - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 16, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STH, tmpReg, dstReg, opnd->object, offset); - extra += 2; - setpcodeflags(opnd->flags); - } else { - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset); - setpcodeflags(opnd->flags); - - emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 1); - extra += 2; - setpcodeflags(opnd->flags); - } - if (len == 3) { - emitpcode(PC_RLWINM, tmpReg, srcReg, 24, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + extra); - setpcodeflags(opnd->flags); - } - break; - case 4: - if (align > 2) { - load_store_register(PC_STW, srcReg, dstReg, opnd->object, offset); - setpcodeflags(opnd->flags); - } else if (align > 1) { - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 16, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STH, tmpReg, dstReg, opnd->object, offset); - setpcodeflags(opnd->flags); - - load_store_register(PC_STH, srcReg, dstReg, opnd->object, offset + 2); - setpcodeflags(opnd->flags); - } else { - tmpReg = used_virtual_registers[RegClass_GPR]++; - emitpcode(PC_RLWINM, tmpReg, srcReg, 8, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset); - setpcodeflags(opnd->flags); - - emitpcode(PC_RLWINM, tmpReg, srcReg, 16, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 1); - setpcodeflags(opnd->flags); - - emitpcode(PC_RLWINM, tmpReg, srcReg, 24, 24, 31); - setpcodeflags(opnd->flags); - load_store_register(PC_STB, tmpReg, dstReg, opnd->object, offset + 2); - setpcodeflags(opnd->flags); - - load_store_register(PC_STB, srcReg, dstReg, opnd->object, offset + 3); - setpcodeflags(opnd->flags); - } - break; - } -} - -void store_small_block_from_reg(short srcReg, Operand *dstOpnd, Type *type, SInt32 align) { - short tmpReg; - - coerce_to_addressable(dstOpnd); - - if (dstOpnd->optype == OpndType_IndirectGPR_Indexed) { - CError_FATAL(839); - - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_address(tmpReg, dstOpnd); - dstOpnd->optype = OpndType_IndirectGPR_ImmOffset; - dstOpnd->reg = tmpReg; - dstOpnd->object = NULL; - dstOpnd->immOffset = 0; - } - - if (copts.misaligned_mem_access) - align = 4; - - store_word_of_small_struct(srcReg, dstOpnd->reg, dstOpnd, dstOpnd->immOffset, type->size, align); -} - -void store_small_block_from_reg_pair(short srcRegLo, short srcRegHi, Operand *dstOpnd, Type *type, SInt32 align) { - short tmpReg; - - coerce_to_addressable(dstOpnd); - - if (dstOpnd->optype == OpndType_IndirectGPR_Indexed) { - CError_FATAL(860); - - tmpReg = used_virtual_registers[RegClass_GPR]++; - load_address(tmpReg, dstOpnd); - dstOpnd->optype = OpndType_IndirectGPR_ImmOffset; - dstOpnd->reg = tmpReg; - dstOpnd->object = NULL; - dstOpnd->immOffset = 0; - } - - if (copts.misaligned_mem_access) - align = 4; - - store_word_of_small_struct( - srcRegLo, dstOpnd->reg, dstOpnd, - dstOpnd->immOffset + low_offset, type->size - 4, align); - store_word_of_small_struct( - srcRegHi, dstOpnd->reg, dstOpnd, - dstOpnd->immOffset + high_offset, 4, align); -} |