From 82e23e60f51f063a07b8f55312efdcbae4dfd813 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 11 Jul 2002 07:42:31 +0000 Subject: [PATCH] * fixed nppccnv and enabled it - removed PPC specific second_int_to_int and use the generic one instead --- compiler/powerpc/cpunode.pas | 7 +- compiler/powerpc/nppccnv.pas | 177 ++++++++++------------------------- 2 files changed, 55 insertions(+), 129 deletions(-) diff --git a/compiler/powerpc/cpunode.pas b/compiler/powerpc/cpunode.pas index 30e14b94c3..c7463d1346 100644 --- a/compiler/powerpc/cpunode.pas +++ b/compiler/powerpc/cpunode.pas @@ -31,6 +31,7 @@ unit cpunode; uses // nppcadd, // nppccal, + nppccnv, // nppccon, // nppcflw, nppcmat, @@ -47,7 +48,11 @@ unit cpunode; end. { $Log$ - Revision 1.5 2002-05-18 13:34:26 peter + Revision 1.6 2002-07-11 07:42:31 jonas + * fixed nppccnv and enabled it + - removed PPC specific second_int_to_int and use the generic one instead + + Revision 1.5 2002/05/18 13:34:26 peter * readded missing revisions Revision 1.4 2002/05/16 19:46:53 carl diff --git a/compiler/powerpc/nppccnv.pas b/compiler/powerpc/nppccnv.pas index aab44aaf38..f35d520e7b 100644 --- a/compiler/powerpc/nppccnv.pas +++ b/compiler/powerpc/nppccnv.pas @@ -32,8 +32,7 @@ interface type tppctypeconvnode = class(tcgtypeconvnode) protected - function first_int_to_int: tnode; override; - procedure second_int_to_int;override; + { procedure second_int_to_int;override; } { procedure second_string_to_string;override; } { procedure second_cstring_to_pchar;override; } { procedure second_string_to_chararray;override; } @@ -43,7 +42,7 @@ interface { procedure second_chararray_to_string;override; } { procedure second_char_to_string;override; } procedure second_int_to_real;override; - { procedure second_real_to_real;override; } + procedure second_real_to_real;override; { procedure second_cord_to_pointer;override; } { procedure second_proc_to_procvar;override; } { procedure second_bool_to_int;override; } @@ -54,17 +53,17 @@ interface { procedure second_class_to_intf;override; } { procedure second_char_to_char;override; } procedure pass_2;override; - procedure second_call_helper(c : tconverttype); + procedure second_call_helper(c : tconverttype); override; end; implementation uses verbose,globals,systems, - symconst,symdef,aasm, + symconst,symdef,aasmbase,aasmtai, cgbase,pass_1,pass_2, ncon,ncal, - cpubase,cpuasm, + cpubase,aasmcpu, rgobj,tgobj,cgobj,cginfo; @@ -105,116 +104,6 @@ implementation SecondTypeConv *****************************************************************************} - - procedure tppctypeconvnode.second_int_to_int; - var - fromsize, - tosize : longint; - opsize, - tempsize : tcgsize; - - begin - { insert range check if not explicit conversion } - if not(nf_explizit in flags) then - cg.g_rangecheck(exprasmlist,left,resulttype.def); - - fromsize := left.resulttype.def.size; - tosize := resulttype.def.size; - { is the result size smaller ? } - if tosize < fromsize then - begin - opsize := def_cgsize(resulttype.def); - case left.location.loc of - LOC_REGISTER,LOC_CREGISTER: - begin - if location.loc = LOC_REGISTER then - location.register:= left.location.register - else - location.register := rg.getregisterint(exprasmlist); - case opsize of - OS_8: - exprasmlist.concat(taicpu.op_reg_reg_const_const_const( - A_RLWINM,location.register,left.location.register, - 0,24,31)); - OS_S8: - exprasmlist.concat(taicpu.op_reg_reg(A_EXTSB, - location.register,left.location.register)); - OS_16: - exprasmlist.concat(taicpu.op_reg_reg_const_const_const( - A_RLWINM,location.register,left.location.register, - 0,16,31)); - OS_S16: - exprasmlist.concat(taicpu.op_reg_reg(A_EXTSH, - location.register,left.location.register)); - else - begin - if location.register <> left.location.register then - exprasmlist.concat(taicpu.op_reg_reg(A_MR, - location.register,left.location.register)); - { we can release the upper register } - if opsize in [OS_64,OS_S64] then - rg.ungetregister(exprasmlist,left.location.registerhigh); - end; - end; - end; - LOC_REFERENCE,LOC_CREFERENCE: - begin - set_location(location,left.location); - inc(location.reference.offset,fromsize-tosize); - end; - end; - end - { is the result size bigger ? } - else if resulttype.def.size>left.resulttype.def.size then - begin - opsize := int_cgsize(fromsize); - location.loc := LOC_REGISTER; - case left.location.loc of - LOC_REFERENCE,LOC_CREFERENCE: - begin - reference_release(exprasmlist,left.location.reference); - location.register := rg.getregisterint(exprasmlist); - if not (opsize in [OS_64,OS_S64]) then - tempsize := pred(opsize) - else - tempsize := opsize; - { this one takes care of the necessary sign extensions } - cg.a_load_ref_reg(exprasmlist,tempsize, - left.location.reference,location.register); - tg.ungetiftemp(exprasmlist,left.location.reference); - end; - LOC_CREGISTER: - { since we only have 32bit registers and everything is } - { always loaded with sign-extending or zeroeing } - { instructions as appropriate, the source will contain } - { the correct value already, so simply copy it } - begin - location.register := rg.getregisterint(exprasmlist); - exprasmlist.concat(taicpu.op_reg_reg(A_MR,location.register, - left.location.register)); - end; - { see LOC_CREGISTER } - LOC_REGISTER:; - end; - { sign extend even further if necessary } - if opsize in [OS_64,OS_S64] then - begin - location.registerhigh := rg.getregisterint(exprasmlist); - if (opsize = OS_64) or - not (is_signed(left.resulttype.def)) then - cg.a_load_const_reg(exprasmlist,OS_32,0, - location.registerhigh) - else - { duplicate the sign bit 32 times in the high reg } - exprasmlist.concat(taicpu.op_reg_reg_const(A_SRAWI, - location.registerhigh,location.register,31)); - end; - end - else - set_location(location,left.location); - end; - - procedure tppctypeconvnode.second_int_to_real; type @@ -225,8 +114,12 @@ implementation tempconst: trealconstnode; ref: treference; valuereg, tempreg, leftreg, tmpfpureg: tregister; - signed: boolean; + signed, valuereg_is_scratch: boolean; begin + + valuereg_is_scratch := false; + location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); + { the code here comes from the PowerPC Compiler Writer's Guide } { * longint to double } @@ -278,7 +171,10 @@ implementation begin leftreg := left.location.register; if signed then - valuereg := cg.get_scratch_reg_int(exprasmlist) + begin + valuereg := cg.get_scratch_reg_int(exprasmlist); + valuereg_is_scratch := true; + end else valuereg := leftreg; end; @@ -286,6 +182,7 @@ implementation begin leftreg := cg.get_scratch_reg_int(exprasmlist); valuereg := leftreg; + valuereg_is_scratch := true; cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def), left.location.reference,leftreg); end @@ -295,11 +192,15 @@ implementation tempreg := cg.get_scratch_reg_int(exprasmlist); exprasmlist.concat(taicpu.op_reg_const(A_LIS,tempreg,$4330)); cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref); + cg.free_scratch_reg(exprasmlist,tempreg); if signed then exprasmlist.concat(taicpu.op_reg_reg_const(A_XORIS,valuereg, - leftreg,$8000)); + leftreg,smallint($8000))); inc(ref.offset,4); cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref); + dec(ref.offset,4); + if (valuereg_is_scratch) then + cg.free_scratch_reg(exprasmlist,valuereg); if (left.location.loc = LOC_REGISTER) or ((left.location.loc = LOC_CREGISTER) and @@ -310,23 +211,40 @@ implementation tmpfpureg := rg.getregisterfpu(exprasmlist); exprasmlist.concat(taicpu.op_reg_ref(A_LFD,tmpfpureg, - newreference(tempconst.location.reference))); + tempconst.location.reference)); tempconst.free; location.register := rg.getregisterfpu(exprasmlist); exprasmlist.concat(taicpu.op_reg_ref(A_LFD,location.register, - newreference(ref))); + ref)); - { restore original offset before ungeting the tempref } - dec(ref.offset,4); tg.ungetiftemp(exprasmlist,ref); exprasmlist.concat(taicpu.op_reg_reg_reg(A_FSUB,location.register, location.register,tmpfpureg)); rg.ungetregisterfpu(exprasmlist,tmpfpureg); + + { work around bug in some PowerPC processors } + if (tfloatdef(resulttype.def).typ = s32real) then + exprasmlist.concat(taicpu.op_reg_reg(A_FRSP,location.register, + location.register)); end; + procedure tppctypeconvnode.second_real_to_real; + begin + inherited second_real_to_real; + { work around bug in some powerpc processors where doubles aren't } + { properly converted to singles } + if (tfloatdef(left.resulttype.def).typ = s64real) and + (tfloatdef(resulttype.def).typ = s32real) then + exprasmlist.concat(taicpu.op_reg_reg(A_FRSP,location.register, + location.register)); + end; + + + + procedure tppctypeconvnode.second_int_to_bool; var hreg1, @@ -334,17 +252,16 @@ implementation resflags : tresflags; opsize : tcgsize; begin - clear_location(location); { byte(boolean) or word(wordbool) or longint(longbool) must } { be accepted for var parameters } if (nf_explizit in flags) and (left.resulttype.def.size=resulttype.def.size) and (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then begin - set_location(location,left.location); + location_copy(location,left.location); exit; end; - location.loc:=LOC_REGISTER; + location_reset(location,LOC_REGISTER,def_cgsize(left.resulttype.def)); opsize := def_cgsize(left.resulttype.def); case left.location.loc of LOC_CREFERENCE,LOC_REFERENCE,LOC_REGISTER,LOC_CREGISTER : @@ -443,7 +360,7 @@ implementation if not(convtype in [tc_bool_2_int,tc_bool_2_bool]) then begin secondpass(left); - set_location(location,left.location); + location_copy(location,left.location); if codegenerror then exit; end; @@ -456,7 +373,11 @@ begin end. { $Log$ - Revision 1.9 2002-05-20 13:30:42 carl + Revision 1.10 2002-07-11 07:42:31 jonas + * fixed nppccnv and enabled it + - removed PPC specific second_int_to_int and use the generic one instead + + Revision 1.9 2002/05/20 13:30:42 carl * bugfix of hdisponen (base must be set, not index) * more portability fixes