ir.c
// Copy struct/unions using registers
//
// splay_offsets is used when copying a struct with SSE values from the vararg register
// save area. The SSE registers are saved with an annoying offset of 16 instead of 8.
Copy struct/unions using registers
splay_offsets is used when copying a struct with SSE values from the vararg register
save area. The SSE registers are saved with an annoying offset of 16 instead of 8.
Copy struct / unions using registers splay_offsets is used when copying a struct with SSE values from the vararg register save area . The SSE registers are saved with an annoying offset of 16 instead of 8 .
Tac *add_memory_copy_with_registers(Function *function, Tac *ir, Value *dst, Value *src1, int size, int splay_offsets) {
    int dst_offset = dst->offset;
    int src1_offset = src1->offset;
    for (int i = 3; i >= 0; i -= 1) {
        int step = 1 << i;
        while (size >= step) {
            Value *temp_value = new_value();
            temp_value->type = new_type(TYPE_CHAR + i);
            temp_value->vreg = ++function->vreg_count;
            Value *offsetted_dst = dup_value(dst);
            offsetted_dst->offset = dst_offset;
            offsetted_dst->type = temp_value->type;
            Value *offsetted_src1 = dup_value(src1);
            int splayed_offset = (splay_offsets && src1_offset >= 8) ? src1_offset + 8 : src1_offset;
            offsetted_src1->offset = splayed_offset;
            offsetted_src1->type = temp_value->type;
            if (src1->is_lvalue && src1->vreg) {
                Value *indirect_src1 = dup_value(offsetted_src1);
                indirect_src1->type = make_pointer(temp_value->type);
                indirect_src1->is_lvalue = 0;
                ir = insert_instruction_after_from_operation(ir, IR_INDIRECT, temp_value, indirect_src1, 0);
            } else
                ir = insert_instruction_after_from_operation(ir, IR_MOVE, temp_value, offsetted_src1, 0);
            ir = insert_instruction_after_from_operation(ir, IR_MOVE, offsetted_dst, temp_value, 0);
            size -= step;
            dst_offset += step;
            src1_offset += step;
        }
    }
    return ir;
}
Tac * add_memory_copy_with_registers ( Function * function , Tac * ir , Value * dst , Value * src1 , int size , int splay_offsets ) { int dst_offset = dst -> offset ; int src1_offset = src1 -> offset ; for ( int i = 3 ; i >= 0 ; i -= 1 ) { int step = 1 << i ; while ( size >= step ) { Value * temp_value = new_value ( ) ; temp_value -> type = new_type ( TYPE_CHAR + i ) ; temp_value -> vreg = ++ function -> vreg_count ; Value * offsetted_dst = dup_value ( dst ) ; offsetted_dst -> offset = dst_offset ; offsetted_dst -> type = temp_value -> type ; Value * offsetted_src1 = dup_value ( src1 ) ; int splayed_offset = ( splay_offsets && src1_offset >= 8 ) ? src1_offset + 8 : src1_offset ; offsetted_src1 -> offset = splayed_offset ; offsetted_src1 -> type = temp_value -> type ; if ( src1 -> is_lvalue && src1 -> vreg ) { Value * indirect_src1 = dup_value ( offsetted_src1 ) ; indirect_src1 -> type = make_pointer ( temp_value -> type ) ; indirect_src1 -> is_lvalue = 0 ; ir = insert_instruction_after_from_operation ( ir , IR_INDIRECT , temp_value , indirect_src1 , 0 ) ; } else ir = insert_instruction_after_from_operation ( ir , IR_MOVE , temp_value , offsetted_src1 , 0 ) ; ir = insert_instruction_after_from_operation ( ir , IR_MOVE , offsetted_dst , temp_value , 0 ) ; size -= step ; dst_offset += step ; src1_offset += step ; } } return ir ; }
Copy struct/unions using registers
splay_offsets is used when copying a struct with SSE values from the vararg register
save area.
Copy struct / unions using registers splay_offsets is used when copying a struct with SSE values from the vararg register save area .
// Do moves of size 8, 4, 2, 1 in order until there are no moves left // Make it a pointer and add an indirect instruction