diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index f9c4bde801..1b184ce010 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -691,19 +691,28 @@ unit cgx86; procedure tcgx86.a_loadmm_reg_reg(list: taasmoutput; fromsize, tosize : tcgsize;reg1, reg2: tregister;shuffle : pmmshuffle); - begin - if shuffle=nil then - begin - if fromsize=tosize then - list.concat(taicpu.op_reg_reg(A_MOVAPS,S_NO,reg1,reg2)) - else - internalerror(200312202); - end - else if shufflescalar(shuffle) then - list.concat(taicpu.op_reg_reg(get_scalar_mm_op(fromsize,tosize),S_NO,reg1,reg2)) - else - internalerror(200312201); - end; + var + instr : taicpu; + begin + if shuffle=nil then + begin + if fromsize=tosize then + instr:=taicpu.op_reg_reg(A_MOVAPS,S_NO,reg1,reg2) + else + internalerror(200312202); + end + else if shufflescalar(shuffle) then + instr:=taicpu.op_reg_reg(get_scalar_mm_op(fromsize,tosize),S_NO,reg1,reg2) + else + internalerror(200312201); + case get_scalar_mm_op(fromsize,tosize) of + A_MOVSS, + A_MOVSD, + A_MOVQ: + add_move_instruction(instr); + end; + list.concat(instr); + end; procedure tcgx86.a_loadmm_ref_reg(list: taasmoutput; fromsize, tosize : tcgsize;const ref: treference; reg: tregister;shuffle : pmmshuffle); @@ -787,7 +796,7 @@ unit cgx86; A_NOP,A_ADDPS,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_XORPS ), ( { OS_F64 } - A_NOP,A_ADDPD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_XORPS + A_NOP,A_ADDPD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_XORPD ) ) ); @@ -1720,7 +1729,11 @@ unit cgx86; end. { $Log$ - Revision 1.136 2004-11-01 23:30:11 peter + Revision 1.137 2004-11-02 18:23:16 florian + * fixed - + * information about simple moves for sse is given to the register allocator + + Revision 1.136 2004/11/01 23:30:11 peter * support > 32bit accesses for x86_64 * rewrote array size checking to support 64bit diff --git a/compiler/x86/nx86mat.pas b/compiler/x86/nx86mat.pas index 2c43117489..a4351306f1 100644 --- a/compiler/x86/nx86mat.pas +++ b/compiler/x86/nx86mat.pas @@ -161,21 +161,40 @@ interface procedure tx86unaryminusnode.second_float; var reg : tregister; + href : treference; + l1 : tasmlabel; begin secondpass(left); if expectloc=LOC_MMREGISTER then begin - reg:=cg.getmmregister(exprasmlist,OS_M128); - { zero out the register - op size doesn't matter } - cg.a_opmm_reg_reg(exprasmlist,OP_XOR,OS_F32,reg,reg,nil); - { move to a mm compatible location } - if left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER] then - location_force_mem(exprasmlist,left.location); - cg.a_opmm_loc_reg(exprasmlist,OP_SUB,left.location.size,left.location,reg,mms_movescalar); + location_force_mmregscalar(exprasmlist,left.location,false); location_reset(location,LOC_MMREGISTER,def_cgsize(resulttype.def)); - location.register:=reg; + + { make life of register allocator easier } + location.register:=cg.getmmregister(exprasmlist,OS_M128); + cg.a_loadmm_reg_reg(exprasmlist,def_cgsize(resulttype.def),def_cgsize(resulttype.def),left.location.register,location.register,mms_movescalar); + + reg:=cg.getmmregister(exprasmlist,OS_M128); + + objectlibrary.getdatalabel(l1); + consts.concat(Tai_label.Create(l1)); + case def_cgsize(resulttype.def) of + OS_F32: + consts.concat(tai_const.create_32bit(1 shl 31)); + OS_F64: + begin + consts.concat(tai_const.create_32bit(0)); + consts.concat(tai_const.create_32bit(-(1 shl 31))); + end + else + internalerror(2004110215); + end; + + reference_reset_symbol(href,l1,0); + cg.a_loadmm_ref_reg(exprasmlist,def_cgsize(resulttype.def),def_cgsize(resulttype.def),href,reg,mms_movescalar); + + cg.a_opmm_reg_reg(exprasmlist,OP_XOR,left.location.size,reg,location.register,nil); end else begin @@ -304,7 +323,11 @@ end. { $Log$ - Revision 1.7 2004-10-31 21:45:04 peter + Revision 1.8 2004-11-02 18:23:16 florian + * fixed - + * information about simple moves for sse is given to the register allocator + + Revision 1.7 2004/10/31 21:45:04 peter * generic tlocation * move tlocation to cgutils