From d91c88014879ef31f55023d6fb2ab938397491c1 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 3 Jun 2003 21:11:09 +0000 Subject: [PATCH] * cg.a_load_* get a from and to size specifier * makeregsize only accepts newregister * i386 uses generic tcgnotnode,tcgunaryminus --- compiler/cg64f32.pas | 80 +++---- compiler/cg64f64.pas | 15 +- compiler/cgobj.pas | 131 +++++------ compiler/i386/cgcpu.pas | 26 ++- compiler/i386/n386cnv.pas | 13 +- compiler/i386/n386mat.pas | 468 ++++++++++++++++---------------------- compiler/i386/n386obj.pas | 9 +- compiler/i386/n386set.pas | 27 ++- compiler/i386/rgcpu.pas | 93 +------- compiler/ncgcal.pas | 37 +-- compiler/ncgcnv.pas | 21 +- compiler/ncgflw.pas | 13 +- compiler/ncginl.pas | 28 ++- compiler/ncgld.pas | 44 ++-- compiler/ncgmat.pas | 202 ++++++++-------- compiler/ncgmem.pas | 21 +- compiler/ncgopt.pas | 15 +- compiler/ncgset.pas | 150 ++++++------ compiler/ncgutil.pas | 88 +++---- compiler/regvars.pas | 18 +- compiler/rgobj.pas | 17 +- compiler/x86/cgx86.pas | 431 +++++++++++++++++------------------ compiler/x86/cpubase.pas | 17 +- 23 files changed, 945 insertions(+), 1019 deletions(-) diff --git a/compiler/cg64f32.pas b/compiler/cg64f32.pas index 4c229dbdbf..9d6cfe750a 100644 --- a/compiler/cg64f32.pas +++ b/compiler/cg64f32.pas @@ -84,8 +84,7 @@ unit cg64f32; } function optimize64_op_const_reg(list: taasmoutput; var op: topcg; var a : qword; var reg: tregister64): boolean;override; - procedure g_rangecheck64(list: taasmoutput; const p: tnode; - const todef: tdef); override; + procedure g_rangecheck64(list: taasmoutput; const l:tlocation;fromdef,todef: tdef); override; end; {# Creates a tregister64 record from 2 32 Bit registers. } @@ -131,10 +130,10 @@ unit cg64f32; reg.reglo:=reg.reghi; reg.reghi:=tmpreg; end; - cg.a_load_reg_ref(list,OS_32,reg.reglo,ref); + cg.a_load_reg_ref(list,OS_32,OS_32,reg.reglo,ref); tmpref := ref; inc(tmpref.offset,4); - cg.a_load_reg_ref(list,OS_32,reg.reghi,tmpref); + cg.a_load_reg_ref(list,OS_32,OS_32,reg.reghi,tmpref); end; procedure tcg64f32.a_load64_const_ref(list : taasmoutput;value : qword;const ref : treference); @@ -190,7 +189,7 @@ unit cg64f32; cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.index,tmpreg); tmpref.index:=tmpreg; end; - cg.a_load_ref_reg(list,OS_32,tmpref,reg.reglo); + cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg.reglo); inc(tmpref.offset,4); {$ifdef newra} if delete then @@ -199,7 +198,7 @@ unit cg64f32; reference_release(list,tmpref); end; {$endif} - cg.a_load_ref_reg(list,OS_32,tmpref,reg.reghi); + cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg.reghi); {$ifdef newra} if got_scratch then rg.ungetregisterint(list,tmpreg); @@ -295,12 +294,12 @@ unit cg64f32; tmpref: treference; begin if target_info.endian = endian_big then - cg.a_load_reg_ref(list,OS_32,reg,ref) + cg.a_load_reg_ref(list,OS_32,OS_32,reg,ref) else begin tmpref := ref; inc(tmpref.offset,4); - cg.a_load_reg_ref(list,OS_32,reg,tmpref) + cg.a_load_reg_ref(list,OS_32,OS_32,reg,tmpref) end; end; @@ -309,12 +308,12 @@ unit cg64f32; tmpref: treference; begin if target_info.endian = endian_little then - cg.a_load_reg_ref(list,OS_32,reg,ref) + cg.a_load_reg_ref(list,OS_32,OS_32,reg,ref) else begin tmpref := ref; inc(tmpref.offset,4); - cg.a_load_reg_ref(list,OS_32,reg,tmpref) + cg.a_load_reg_ref(list,OS_32,OS_32,reg,tmpref) end; end; @@ -323,12 +322,12 @@ unit cg64f32; tmpref: treference; begin if target_info.endian = endian_big then - cg.a_load_ref_reg(list,OS_32,ref,reg) + cg.a_load_ref_reg(list,OS_32,OS_32,ref,reg) else begin tmpref := ref; inc(tmpref.offset,4); - cg.a_load_ref_reg(list,OS_32,tmpref,reg) + cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg) end; end; @@ -337,12 +336,12 @@ unit cg64f32; tmpref: treference; begin if target_info.endian = endian_little then - cg.a_load_ref_reg(list,OS_32,ref,reg) + cg.a_load_ref_reg(list,OS_32,OS_32,ref,reg) else begin tmpref := ref; inc(tmpref.offset,4); - cg.a_load_ref_reg(list,OS_32,tmpref,reg) + cg.a_load_ref_reg(list,OS_32,OS_32,tmpref,reg) end; end; @@ -623,7 +622,7 @@ unit cg64f32; end; - procedure tcg64f32.g_rangecheck64(list : taasmoutput;const p : tnode;const todef : tdef); + procedure tcg64f32.g_rangecheck64(list : taasmoutput;const l:tlocation;fromdef,todef:tdef); var neglabel, @@ -631,14 +630,13 @@ unit cg64f32; endlabel: tasmlabel; hreg : tregister; hdef : torddef; - fromdef : tdef; opsize : tcgsize; oldregisterdef: boolean; from_signed,to_signed: boolean; got_scratch: boolean; + temploc : tlocation; begin - fromdef:=p.resulttype.def; from_signed := is_signed(fromdef); to_signed := is_signed(todef); @@ -648,9 +646,9 @@ unit cg64f32; registerdef := false; { get the high dword in a register } - if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then + if l.loc in [LOC_REGISTER,LOC_CREGISTER] then begin - hreg := p.location.registerhigh; + hreg := l.registerhigh; got_scratch := false end else @@ -661,7 +659,7 @@ unit cg64f32; hreg := cg.get_scratch_reg_int(list,OS_INT); {$endif} got_scratch := true; - a_load64high_ref_reg(list,p.location.reference,hreg); + a_load64high_ref_reg(list,l.reference,hreg); end; objectlibrary.getlabel(poslabel); @@ -689,14 +687,12 @@ unit cg64f32; { simple cardinal } cg.a_label(list,poslabel); hdef:=torddef.create(u32bit,0,cardinal($ffffffff)); - { the real p.resulttype.def is already saved in fromdef } - p.resulttype.def := hdef; { no use in calling just "g_rangecheck" since that one will } { simply call the inherited method too (JM) } - cg.g_rangecheck(list,p,todef); + location_copy(temploc,l); + temploc.size:=OS_32; + cg.g_rangecheck(list,temploc,hdef,todef); hdef.free; - { restore original resulttype.def } - p.resulttype.def := fromdef; if from_signed and to_signed then begin @@ -705,9 +701,9 @@ unit cg64f32; { if the high dword = $ffffffff, then the low dword (when } { considered as a longint) must be < 0 } cg.a_label(list,neglabel); - if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then + if l.loc in [LOC_REGISTER,LOC_CREGISTER] then begin - hreg := p.location.registerlow; + hreg := l.registerlow; got_scratch := false end else @@ -718,7 +714,7 @@ unit cg64f32; hreg := cg.get_scratch_reg_int(list,OS_INT); {$endif} got_scratch := true; - a_load64low_ref_reg(list,p.location.reference,hreg); + a_load64low_ref_reg(list,l.reference,hreg); end; { get a new neglabel (JM) } objectlibrary.getlabel(neglabel); @@ -738,14 +734,13 @@ unit cg64f32; { longint($80000000) and -1 (JM) } cg.a_label(list,neglabel); hdef:=torddef.create(s32bit,longint($80000000),-1); - p.resulttype.def := hdef; - cg.g_rangecheck(list,p,todef); + location_copy(temploc,l); + temploc.size:=OS_32; + cg.g_rangecheck(list,temploc,hdef,todef); hdef.free; cg.a_label(list,endlabel); end; registerdef := oldregisterdef; - p.resulttype.def := fromdef; - { restore p's resulttype.def } end else { todef = 64bit int } @@ -759,17 +754,17 @@ unit cg64f32; (torddef(fromdef).typ = u64bit)) then begin { in all cases, there is only a problem if the higest bit is set } - if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then + if l.loc in [LOC_REGISTER,LOC_CREGISTER] then begin if is_64bit(fromdef) then begin - hreg := p.location.registerhigh; + hreg := l.registerhigh; opsize := OS_32; end else begin - hreg := p.location.register; - opsize := def_cgsize(p.resulttype.def); + hreg := l.register; + opsize := def_cgsize(fromdef); end; got_scratch := false; end @@ -782,11 +777,11 @@ unit cg64f32; {$endif} got_scratch := true; - opsize := def_cgsize(p.resulttype.def); + opsize := def_cgsize(fromdef); if opsize in [OS_64,OS_S64] then - a_load64high_ref_reg(list,p.location.reference,hreg) + a_load64high_ref_reg(list,l.reference,hreg) else - cg.a_load_ref_reg(list,opsize,p.location.reference,hreg); + cg.a_load_ref_reg(list,opsize,OS_INT,l.reference,hreg); end; objectlibrary.getlabel(poslabel); cg.a_cmp_const_reg_label(list,opsize,OC_GTE,0,hreg,poslabel); @@ -909,7 +904,12 @@ begin end. { $Log$ - Revision 1.46 2003-06-03 13:01:59 daniel + Revision 1.47 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.46 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.45 2003/06/01 21:38:06 peter diff --git a/compiler/cg64f64.pas b/compiler/cg64f64.pas index 5f7bb5c773..1490dcc21a 100644 --- a/compiler/cg64f64.pas +++ b/compiler/cg64f64.pas @@ -35,7 +35,7 @@ unit cg64f64; aasmbase,aasmtai,aasmcpu, cpuinfo, cpubase, cginfo, cgobj, - node,symtype; + symtype; type {# Defines all the methods required on 32-bit processors @@ -77,8 +77,7 @@ unit cg64f64; function optimize64_op_const_reg(list: taasmoutput; var op: topcg; var a : qword; var reg: tregister64): boolean;override; { override to catch 64bit rangechecks } - procedure g_rangecheck64(list: taasmoutput; const p: tnode; - const todef: tdef); override; + procedure g_rangecheck64(list: taasmoutput; const l: tlocation;fromdef,todef: tdef); override; end; implementation @@ -198,8 +197,7 @@ unit cg64f64; begin end; - procedure tcg64f64.g_rangecheck64(list: taasmoutput; const p: tnode; - const todef: tdef); + procedure tcg64f64.g_rangecheck64(list: taasmoutput; const p: tnode;def: tdef); begin end; @@ -225,7 +223,12 @@ unit cg64f64; end. { $Log$ - Revision 1.7 2003-05-30 23:49:18 jonas + Revision 1.8 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.7 2003/05/30 23:49:18 jonas * a_load_loc_reg now has an extra size parameter for the destination register (properly fixes what I worked around in revision 1.106 of ncgutil.pas) diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 199dc90407..df8868e227 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -41,7 +41,7 @@ unit cgobj; cclasses,aasmbase,aasmtai,aasmcpu,symtable, cpubase,cpuinfo, cginfo, - symconst,symbase,symtype,symdef,node + symconst,symbase,symtype,symdef {$ifdef delphi} ,dmisc {$endif} @@ -193,13 +193,13 @@ unit cgobj; procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);virtual; abstract; procedure a_load_const_ref(list : taasmoutput;size : tcgsize;a : aword;const ref : treference);virtual; procedure a_load_const_loc(list : taasmoutput;a : aword;const loc : tlocation); - procedure a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);virtual; abstract; - procedure a_load_reg_reg(list : taasmoutput;fromsize, tosize : tcgsize;reg1,reg2 : tregister);virtual; abstract; - procedure a_load_reg_loc(list : taasmoutput;size : tcgsize;reg : tregister;const loc: tlocation); - procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);virtual; abstract; - procedure a_load_ref_ref(list : taasmoutput;size : tcgsize;const sref : treference;const dref : treference);virtual; - procedure a_load_loc_reg(list : taasmoutput; dstsize: tcgsize; const loc: tlocation; reg : tregister); - procedure a_load_loc_ref(list : taasmoutput;const loc: tlocation; const ref : treference); + procedure a_load_reg_ref(list : taasmoutput;fromsize,tosize : tcgsize;register : tregister;const ref : treference);virtual; abstract; + procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);virtual; abstract; + procedure a_load_reg_loc(list : taasmoutput;fromsize : tcgsize;reg : tregister;const loc: tlocation); + procedure a_load_ref_reg(list : taasmoutput;fromsize,tosize : tcgsize;const ref : treference;register : tregister);virtual; abstract; + procedure a_load_ref_ref(list : taasmoutput;fromsize,tosize : tcgsize;const sref : treference;const dref : treference);virtual; + procedure a_load_loc_reg(list : taasmoutput;tosize: tcgsize; const loc: tlocation; reg : tregister); + procedure a_load_loc_ref(list : taasmoutput;tosize: tcgsize; const loc: tlocation; const ref : treference); procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);virtual; abstract; { fpu move instructions } @@ -356,11 +356,10 @@ unit cgobj; @param(p Node which contains the value to check) @param(todef Type definition of node to range check) } - procedure g_rangecheck(list: taasmoutput; const p: tnode; - const todef: tdef); virtual; + procedure g_rangecheck(list: taasmoutput; const l:tlocation; fromdef,todef: tdef); virtual; {# Generates overflow checking code for a node } - procedure g_overflowcheck(list: taasmoutput; const p: tnode); virtual; abstract; + procedure g_overflowcheck(list: taasmoutput; const l:tlocation; def:tdef); virtual; abstract; procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);virtual;abstract; {# Emits instructions which should be emitted when entering @@ -484,8 +483,7 @@ unit cgobj; { override to catch 64bit rangechecks } - procedure g_rangecheck64(list: taasmoutput; const p: tnode; - const todef: tdef);virtual;abstract; + procedure g_rangecheck64(list: taasmoutput; const l:tlocation; fromdef,todef: tdef);virtual;abstract; end; var @@ -613,7 +611,7 @@ unit cgobj; reference_reset(ref); ref.base:=locpara.reference.index; ref.offset:=locpara.reference.offset; - a_load_reg_ref(list,size,r,ref); + a_load_reg_ref(list,size,size,r,ref); end else internalerror(2002071004); @@ -649,7 +647,7 @@ unit cgobj; {$else} hr:=get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,r,hr); + a_load_ref_reg(list,size,size,r,hr); a_param_reg(list,size,hr,locpara); {$ifdef newra} rg.ungetregisterint(list,hr); @@ -714,7 +712,7 @@ unit cgobj; some generic implementations ****************************************************************************} - procedure tcg.a_load_ref_ref(list : taasmoutput;size : tcgsize;const sref : treference;const dref : treference); + procedure tcg.a_load_ref_ref(list : taasmoutput;fromsize,tosize : tcgsize;const sref : treference;const dref : treference); var tmpreg: tregister; @@ -732,7 +730,7 @@ unit cgobj; { doesn't have an 8bit component which is directly addressable) } pushed_reg.enum:=R_INTREGISTER; pushed_reg.number:=NR_NO; - if size in [OS_8,OS_S8] then + if tosize in [OS_8,OS_S8] then {$ifndef newra} if (rg.countunusedregsint = 0) then begin @@ -755,19 +753,19 @@ unit cgobj; end else {$endif} - tmpreg := rg.getregisterint(list,size) + tmpreg := rg.getregisterint(list,tosize) else {$endif i386} {$ifdef newra} - tmpreg:=rg.getregisterint(list,size); + tmpreg:=rg.getregisterint(list,tosize); {$else} - tmpreg := get_scratch_reg_int(list,size); + tmpreg := get_scratch_reg_int(list,tosize); {$endif} - a_load_ref_reg(list,size,sref,tmpreg); - a_load_reg_ref(list,size,tmpreg,dref); + a_load_ref_reg(list,fromsize,tosize,sref,tmpreg); + a_load_reg_ref(list,tosize,tosize,tmpreg,dref); {$ifdef i386} {$ifndef newra} - if size in [OS_8,OS_S8] then + if tosize in [OS_8,OS_S8] then begin if (pushed_reg.number<>NR_NO) then list.concat(taicpu.op_reg(A_POP,S_L,pushed_reg)) @@ -797,7 +795,7 @@ unit cgobj; tmpreg := get_scratch_reg_int(list,size); {$endif} a_load_const_reg(list,size,a,tmpreg); - a_load_reg_ref(list,size,tmpreg,ref); + a_load_reg_ref(list,size,size,tmpreg,ref); {$ifdef newra} rg.ungetregisterint(list,tmpreg); {$else} @@ -819,45 +817,45 @@ unit cgobj; end; - procedure tcg.a_load_reg_loc(list : taasmoutput;size : tcgsize;reg : tregister;const loc: tlocation); + procedure tcg.a_load_reg_loc(list : taasmoutput;fromsize : tcgsize;reg : tregister;const loc: tlocation); begin case loc.loc of LOC_REFERENCE,LOC_CREFERENCE: - a_load_reg_ref(list,loc.size,reg,loc.reference); + a_load_reg_ref(list,fromsize,loc.size,reg,loc.reference); LOC_REGISTER,LOC_CREGISTER: - a_load_reg_reg(list,size,loc.size,reg,loc.register); + a_load_reg_reg(list,fromsize,loc.size,reg,loc.register); else internalerror(200203271); end; end; - procedure tcg.a_load_loc_reg(list : taasmoutput; dstsize: tcgsize; const loc: tlocation; reg : tregister); + procedure tcg.a_load_loc_reg(list : taasmoutput; tosize: tcgsize; const loc: tlocation; reg : tregister); begin case loc.loc of LOC_REFERENCE,LOC_CREFERENCE: - a_load_ref_reg(list,loc.size,loc.reference,reg); + a_load_ref_reg(list,loc.size,tosize,loc.reference,reg); LOC_REGISTER,LOC_CREGISTER: - a_load_reg_reg(list,loc.size,dstsize,loc.register,reg); + a_load_reg_reg(list,loc.size,tosize,loc.register,reg); LOC_CONSTANT: - a_load_const_reg(list,loc.size,loc.value,reg); + a_load_const_reg(list,tosize,loc.value,reg); else internalerror(200109092); end; end; - procedure tcg.a_load_loc_ref(list : taasmoutput;const loc: tlocation; const ref : treference); + procedure tcg.a_load_loc_ref(list : taasmoutput;tosize: tcgsize; const loc: tlocation; const ref : treference); begin case loc.loc of LOC_REFERENCE,LOC_CREFERENCE: - a_load_ref_ref(list,loc.size,loc.reference,ref); + a_load_ref_ref(list,loc.size,tosize,loc.reference,ref); LOC_REGISTER,LOC_CREGISTER: - a_load_reg_ref(list,loc.size,loc.register,ref); + a_load_reg_ref(list,loc.size,tosize,loc.register,ref); LOC_CONSTANT: - a_load_const_ref(list,loc.size,loc.value,ref); + a_load_const_ref(list,tosize,loc.value,ref); else internalerror(200109302); end; @@ -873,7 +871,7 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_address(list); {$endif} - a_load_ref_reg(list,OS_ADDR,ref,tmpreg); + a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,tmpreg); a_call_reg(list,tmpreg); {$ifdef newra} rg.ungetaddressregister(list,tmpreg); @@ -1028,9 +1026,9 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,ref,tmpreg); - a_op_const_reg(list,op,OS_INT,a,tmpreg); - a_load_reg_ref(list,size,tmpreg,ref); + a_load_ref_reg(list,size,size,ref,tmpreg); + a_op_const_reg(list,op,size,a,tmpreg); + a_load_reg_ref(list,size,size,tmpreg,ref); {$ifdef newra} rg.ungetregisterint(list,tmpreg); {$else} @@ -1064,9 +1062,9 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,ref,tmpreg); + a_load_ref_reg(list,size,size,ref,tmpreg); a_op_reg_reg(list,op,size,reg,tmpreg); - a_load_reg_ref(list,size,tmpreg,ref); + a_load_reg_ref(list,size,size,tmpreg,ref); {$ifdef newra} rg.ungetregisterint(list,tmpreg); {$else} @@ -1085,7 +1083,7 @@ unit cgobj; OP_NOT,OP_NEG: { handle it as "load ref,reg; op reg" } begin - a_load_ref_reg(list,size,ref,reg); + a_load_ref_reg(list,size,size,ref,reg); a_op_reg_reg(list,op,size,reg,reg); end; else @@ -1095,7 +1093,7 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,ref,tmpreg); + a_load_ref_reg(list,size,size,ref,tmpreg); a_op_reg_reg(list,op,size,tmpreg,reg); {$ifdef newra} rg.ungetregisterint(list,tmpreg); @@ -1137,7 +1135,7 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,loc.size); {$endif} - a_load_ref_reg(list,loc.size,ref,tmpreg); + a_load_ref_reg(list,loc.size,loc.size,ref,tmpreg); a_op_reg_ref(list,op,loc.size,tmpreg,loc.reference); {$ifdef newra} rg.ungetregisterint(list,tmpreg); @@ -1197,7 +1195,7 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,ref,tmpreg); + a_load_ref_reg(list,size,size,ref,tmpreg); a_cmp_const_reg_label(list,size,cmp_op,a,tmpreg,l); {$ifdef newra} rg.ungetregisterint(list,tmpreg); @@ -1231,7 +1229,7 @@ unit cgobj; {$else} tmpreg := get_scratch_reg_int(list,size); {$endif} - a_load_ref_reg(list,size,ref,tmpreg); + a_load_ref_reg(list,size,size,ref,tmpreg); a_cmp_reg_reg_label(list,size,cmp_op,tmpreg,reg,l); {$ifdef newra} rg.ungetregisterint(list,tmpreg); @@ -1284,8 +1282,7 @@ unit cgobj; else {$endif i386} tmpreg := get_scratch_reg_int(list,size); - {tmpreg := rg.makeregsize(tmpreg,size);} - a_load_ref_reg(list,size,loc.reference,tmpreg); + a_load_ref_reg(list,size,size,loc.reference,tmpreg); a_cmp_ref_reg_label(list,size,cmp_op,ref,tmpreg,l); {$ifdef i386} if size in [OS_8,OS_S8] then @@ -1450,7 +1447,7 @@ unit cgobj; end; - procedure tcg.g_rangecheck(list: taasmoutput; const p: tnode;const todef: tdef); + procedure tcg.g_rangecheck(list: taasmoutput; const l:tlocation;fromdef,todef: tdef); { generate range checking code for the value at location p. The type } { type used is checked against todefs ranges. fromdef (p.resulttype.def) } { is the original type used at that location. When both defs are equal } @@ -1464,24 +1461,22 @@ unit cgobj; var neglabel : tasmlabel; hreg : tregister; - fromdef : tdef; lto,hto, lfrom,hfrom : TConstExprInt; from_signed: boolean; begin { range checking on and range checkable value? } if not(cs_check_range in aktlocalswitches) or - not(todef.deftype in [orddef,enumdef,arraydef]) then + not(fromdef.deftype in [orddef,enumdef,arraydef]) then exit; - if is_64bit(p.resulttype.def) or is_64bit(todef) then + if is_64bit(fromdef) or is_64bit(todef) then begin - cg64.g_rangecheck64(list,p,todef); + cg64.g_rangecheck64(list,l,fromdef,todef); exit; end; { only check when assigning to scalar, subranges are different, } { when todef=fromdef then the check is always generated } - fromdef:=p.resulttype.def; - getrange(p.resulttype.def,lfrom,hfrom); + getrange(fromdef,lfrom,hfrom); getrange(todef,lto,hto); { no range check if from and to are equal and are both longint/dword } { (if we have a 32bit processor) or int64/qword, since such } @@ -1553,17 +1548,10 @@ unit cgobj; {$ifdef newra} hreg:=rg.getregisterint(list,OS_INT); {$else} - hreg := get_scratch_reg_int(list,OS_INT); + hreg:=get_scratch_reg_int(list,OS_INT); {$endif} - if (p.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then - a_op_const_reg_reg(list,OP_SUB,def_cgsize(p.resulttype.def), - aword(lto),p.location.register,hreg) - else - begin - a_load_ref_reg(list,def_cgsize(p.resulttype.def), - p.location.reference,hreg); - a_op_const_reg(list,OP_SUB,OS_INT,aword(lto),hreg); - end; + a_load_loc_reg(list,OS_INT,l,hreg); + a_op_const_reg(list,OP_SUB,OS_INT,aword(lto),hreg); objectlibrary.getlabel(neglabel); a_cmp_const_reg_label(list,OS_INT,OC_BE,aword(hto-lto),hreg,neglabel); { !!! should happen right after the compare (JM) } @@ -1596,7 +1584,7 @@ unit cgobj; tmpreg := get_scratch_reg_int(list,size); {$endif} g_flags2reg(list,size,f,tmpreg); - a_load_reg_ref(list,size,tmpreg,ref); + a_load_reg_ref(list,size,size,tmpreg,ref); {$ifdef newra} rg.ungetregisterint(list,tmpreg); {$else} @@ -1667,7 +1655,7 @@ unit cgobj; begin r.enum:=R_INTREGISTER;; r.number:=NR_FUNCTION_RETURN_REG; - a_load_reg_ref(list, OS_S32, r, href); + a_load_reg_ref(list, OS_S32, OS_32, r, href); end; @@ -1684,7 +1672,7 @@ unit cgobj; begin r.enum:=R_INTREGISTER; r.number:=NR_FUNCTION_RETURN_REG; - a_load_ref_reg(list, OS_S32, href, r); + a_load_ref_reg(list, OS_S32, OS_S32, href, r); end; @@ -1712,7 +1700,12 @@ finalization end. { $Log$ - Revision 1.106 2003-06-03 13:01:59 daniel + Revision 1.107 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.106 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.105 2003/06/01 21:38:06 peter diff --git a/compiler/i386/cgcpu.pas b/compiler/i386/cgcpu.pas index 7f6ad02847..5a3bdfc9a5 100644 --- a/compiler/i386/cgcpu.pas +++ b/compiler/i386/cgcpu.pas @@ -112,6 +112,25 @@ unit cgcpu; var op1,op2 : TAsmOp; begin + case op of + OP_NEG : + begin + if (regsrc.reglo.number<>regdst.reglo.number) then + a_load64_reg_reg(list,regsrc,regdst); + list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reghi)); + list.concat(taicpu.op_reg(A_NEG,S_L,regdst.reglo)); + list.concat(taicpu.op_const_reg(A_SBB,S_L,aword(-1),regdst.reghi)); + exit; + end; + OP_NOT : + begin + if (regsrc.reglo.number<>regdst.reglo.number) then + a_load64_reg_reg(list,regsrc,regdst); + list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reghi)); + list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reglo)); + exit; + end; + end; get_64bit_ops(op,op1,op2); list.concat(taicpu.op_reg_reg(op1,S_L,regsrc.reglo,regdst.reglo)); list.concat(taicpu.op_reg_reg(op2,S_L,regsrc.reghi,regdst.reghi)); @@ -174,7 +193,12 @@ begin end. { $Log$ - Revision 1.34 2003-06-01 21:38:06 peter + Revision 1.35 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.34 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/i386/n386cnv.pas b/compiler/i386/n386cnv.pas index b02acc02a2..ed9dc046b2 100644 --- a/compiler/i386/n386cnv.pas +++ b/compiler/i386/n386cnv.pas @@ -136,12 +136,12 @@ implementation begin href:=left.location.reference; inc(href.offset,4); - cg.a_load_ref_reg(exprasmlist,OS_32,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister); exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister)); - cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hregister); + cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,left.location.reference,hregister); end else - cg.a_load_ref_reg(exprasmlist,left.location.size,left.location.reference,hregister); + cg.a_load_ref_reg(exprasmlist,left.location.size,OS_INT,left.location.reference,hregister); end; else internalerror(2002032218); @@ -358,7 +358,12 @@ begin end. { $Log$ - Revision 1.61 2003-04-30 20:53:32 florian + Revision 1.62 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.61 2003/04/30 20:53:32 florian * error when address of an abstract method is taken * fixed some x86-64 problems * merged some more x86-64 and i386 code diff --git a/compiler/i386/n386mat.pas b/compiler/i386/n386mat.pas index 3476f97d8b..4430e991ba 100644 --- a/compiler/i386/n386mat.pas +++ b/compiler/i386/n386mat.pas @@ -27,7 +27,7 @@ unit n386mat; interface uses - node,nmat; + node,nmat,ncgmat; type ti386moddivnode = class(tmoddivnode) @@ -40,15 +40,22 @@ interface function first_shlshr64bitint: tnode; override; end; - ti386unaryminusnode = class(tunaryminusnode) - function pass_1 : tnode;override; - procedure pass_2;override; + ti386unaryminusnode = class(tcgunaryminusnode) +{$ifdef SUPPORT_MMX} + procedure second_mmx;override; +{$endif SUPPORT_MMX} + procedure second_float;override; + function pass_1:tnode;override; end; - ti386notnode = class(tnotnode) - procedure pass_2;override; + ti386notnode = class(tcgnotnode) + procedure second_boolean;override; +{$ifdef SUPPORT_MMX} + procedure second_mmx;override; +{$endif SUPPORT_MMX} end; + implementation uses @@ -866,12 +873,6 @@ implementation if codegenerror then exit; - registers32:=left.registers32; - registersfpu:=left.registersfpu; -{$ifdef SUPPORT_MMX} - registersmmx:=left.registersmmx; -{$endif SUPPORT_MMX} - if (left.resulttype.def.deftype=floatdef) then begin if (registersfpu < 1) then @@ -879,166 +880,111 @@ implementation expectloc:=LOC_FPUREGISTER; end {$ifdef SUPPORT_MMX} - else if (cs_mmx in aktlocalswitches) and - is_mmx_able_array(left.resulttype.def) then + else + if (cs_mmx in aktlocalswitches) and + is_mmx_able_array(left.resulttype.def) then begin + registers32:=left.registers32; + registersfpu:=left.registersfpu; + registersmmx:=left.registersmmx; if (left.location.loc<>LOC_MMXREGISTER) and (registersmmx<1) then registersmmx:=1; end {$endif SUPPORT_MMX} - else if is_64bitint(left.resulttype.def) then - begin - if (left.location.loc<>LOC_REGISTER) and - (registers32<2) then - registers32:=2; - expectloc:=LOC_REGISTER; - end - else if (left.resulttype.def.deftype=orddef) then - begin - if (left.location.loc<>LOC_REGISTER) and - (registers32<1) then - registers32:=1; - expectloc:=LOC_REGISTER; - end; + else + inherited pass_1; end; - procedure ti386unaryminusnode.pass_2; - - var r:Tregister; - {$ifdef SUPPORT_MMX} - procedure do_mmx_neg; - var - op : tasmop; - r: Tregister; - begin - location_reset(location,LOC_MMXREGISTER,OS_NO); - if cs_mmx_saturation in aktlocalswitches then - case mmx_type(resulttype.def) of - mmxs8bit: - op:=A_PSUBSB; - mmxu8bit: - op:=A_PSUBUSB; - mmxs16bit,mmxfixed16: - op:=A_PSUBSW; - mmxu16bit: - op:=A_PSUBUSW; - end - else - case mmx_type(resulttype.def) of - mmxs8bit,mmxu8bit: - op:=A_PSUBB; - mmxs16bit,mmxu16bit,mmxfixed16: - op:=A_PSUBW; - mmxs32bit,mmxu32bit: - op:=A_PSUBD; - end; - r.enum:=R_MM7; - emit_reg_reg(op,S_NO,location.register,r); - emit_reg_reg(A_MOVQ,S_NO,r,location.register); - end; -{$endif} - + procedure ti386unaryminusnode.second_mmx; + var + r : Tregister; + op : tasmop; begin - if is_64bitint(left.resulttype.def) then - begin - secondpass(left); - - { load left operator in a register } - location_copy(location,left.location); - location_force_reg(exprasmlist,location,OS_64,false); - - emit_reg(A_NOT,S_L,location.registerhigh); - emit_reg(A_NEG,S_L,location.registerlow); - emit_const_reg(A_SBB,S_L,-1,location.registerhigh); - end - else - begin - secondpass(left); - location_reset(location,LOC_REGISTER,OS_INT); - case left.location.loc of - LOC_REGISTER: - begin - location.register:=left.location.register; - emit_reg(A_NEG,S_L,location.register); - end; - LOC_CREGISTER: - begin - location.register:=rg.getregisterint(exprasmlist,OS_INT); - emit_reg_reg(A_MOV,S_L,left.location.register, - location.register); - emit_reg(A_NEG,S_L,location.register); - end; -{$ifdef SUPPORT_MMX} - LOC_MMXREGISTER: - begin - location_copy(location,left.location); - r.enum:=R_MM7; - emit_reg_reg(A_PXOR,S_NO,r,r); - do_mmx_neg; - end; - LOC_CMMXREGISTER: - begin - location.register:=rg.getregistermm(exprasmlist); - r.enum:=R_MM7; - emit_reg_reg(A_PXOR,S_NO,r,r); - emit_reg_reg(A_MOVQ,S_NO,left.location.register, - location.register); - do_mmx_neg; - end; + secondpass(left); + location_reset(location,LOC_MMXREGISTER,OS_NO); + case left.location.loc of + LOC_MMXREGISTER: + begin + location.register:=left.location.register; + r.enum:=R_MM7; + emit_reg_reg(A_PXOR,S_NO,r,r); + end; + LOC_CMMXREGISTER: + begin + location.register:=rg.getregistermm(exprasmlist); + r.enum:=R_MM7; + emit_reg_reg(A_PXOR,S_NO,r,r); + emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register); + end; + LOC_REFERENCE, + LOC_CREFERENCE: + begin + reference_release(exprasmlist,left.location.reference); + r.enum:=R_MM7; + location.register:=rg.getregistermm(exprasmlist); + emit_reg_reg(A_PXOR,S_NO,r,r); + emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register); + end; + else + internalerror(200203225); + end; + if cs_mmx_saturation in aktlocalswitches then + case mmx_type(resulttype.def) of + mmxs8bit: + op:=A_PSUBSB; + mmxu8bit: + op:=A_PSUBUSB; + mmxs16bit,mmxfixed16: + op:=A_PSUBSW; + mmxu16bit: + op:=A_PSUBUSW; + end + else + case mmx_type(resulttype.def) of + mmxs8bit,mmxu8bit: + op:=A_PSUBB; + mmxs16bit,mmxu16bit,mmxfixed16: + op:=A_PSUBW; + mmxs32bit,mmxu32bit: + op:=A_PSUBD; + end; + r.enum:=R_MM7; + emit_reg_reg(op,S_NO,location.register,r); + emit_reg_reg(A_MOVQ,S_NO,r,location.register); + end; {$endif SUPPORT_MMX} - LOC_REFERENCE, - LOC_CREFERENCE: - begin - reference_release(exprasmlist,left.location.reference); - if (left.resulttype.def.deftype=floatdef) then - begin - location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); - location.register.enum:=R_ST; - cg.a_loadfpu_ref_reg(exprasmlist, - def_cgsize(left.resulttype.def), - left.location.reference,location.register); - emit_none(A_FCHS,S_NO); - end -{$ifdef SUPPORT_MMX} - else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(left.resulttype.def) then - begin - r.enum:=R_MM7; - location.register:=rg.getregistermm(exprasmlist); - emit_reg_reg(A_PXOR,S_NO,r,r); - emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register); - do_mmx_neg; - end -{$endif SUPPORT_MMX} - else - begin - location.register:=rg.getregisterint(exprasmlist,OS_INT); - emit_ref_reg(A_MOV,S_L,left.location.reference,location.register); - emit_reg(A_NEG,S_L,location.register); - end; - end; - LOC_FPUREGISTER,LOC_CFPUREGISTER: - begin - { "load st,st" is ignored by the code generator } - r.enum:=R_ST; - cg.a_loadfpu_reg_reg(exprasmlist,left.location.register,r); - location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); - location.register.enum:=R_ST; - emit_none(A_FCHS,S_NO); - end; - else - internalerror(200203225); - end; - end; - { Here was a problem... } - { Operand to be negated always } - { seems to be converted to signed } - { 32-bit before doing neg!! } - { So this is useless... } - { that's not true: -2^31 gives an overflow error if it is negaded (FK) } - { emitoverflowcheck(p);} + + + procedure ti386unaryminusnode.second_float; + var + r : tregister; + begin + secondpass(left); + location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); + case left.location.loc of + LOC_REFERENCE, + LOC_CREFERENCE: + begin + reference_release(exprasmlist,left.location.reference); + location.register.enum:=R_ST; + cg.a_loadfpu_ref_reg(exprasmlist, + def_cgsize(left.resulttype.def), + left.location.reference,location.register); + emit_none(A_FCHS,S_NO); + end; + LOC_FPUREGISTER, + LOC_CFPUREGISTER: + begin + { "load st,st" is ignored by the code generator } + r.enum:=R_ST; + cg.a_loadfpu_reg_reg(exprasmlist,left.location.register,r); + location.register.enum:=R_ST; + emit_none(A_FCHS,S_NO); + end; + end; end; @@ -1046,125 +992,100 @@ implementation TI386NOTNODE *****************************************************************************} - procedure ti386notnode.pass_2; - const - flagsinvers : array[F_E..F_BE] of tresflags = - (F_NE,F_E,F_LE,F_GE,F_L,F_G,F_NC,F_C, - F_BE,F_B,F_AE,F_A); + procedure ti386notnode.second_boolean; var hl : tasmlabel; opsize : topsize; -{$ifdef SUPPORT_MMX} - r,r2 : tregister; -{$endif SUPPORT_MMX} begin - if is_boolean(resulttype.def) then - begin - opsize:=def_opsize(resulttype.def); + opsize:=def_opsize(resulttype.def); - if left.expectloc=LOC_JUMP then - begin - location_reset(location,LOC_JUMP,OS_NO); - hl:=truelabel; - truelabel:=falselabel; - falselabel:=hl; - secondpass(left); - maketojumpbool(exprasmlist,left,lr_load_regvars); - hl:=truelabel; - truelabel:=falselabel; - falselabel:=hl; - end - else - begin - { the second pass could change the location of left } - { if it is a register variable, so we've to do } - { this before the case statement } - secondpass(left); - case left.expectloc of - LOC_FLAGS : - begin - location_release(exprasmlist,left.location); - location_reset(location,LOC_FLAGS,OS_NO); - location.resflags:=flagsinvers[left.location.resflags]; - end; - LOC_CONSTANT, - LOC_REGISTER, - LOC_CREGISTER, - LOC_REFERENCE, - LOC_CREFERENCE : - begin - location_force_reg(exprasmlist,left.location,def_cgsize(resulttype.def),true); - emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register); - location_release(exprasmlist,left.location); - location_reset(location,LOC_FLAGS,OS_NO); - location.resflags:=F_E; - end; - else - internalerror(200203224); + if left.expectloc=LOC_JUMP then + begin + location_reset(location,LOC_JUMP,OS_NO); + hl:=truelabel; + truelabel:=falselabel; + falselabel:=hl; + secondpass(left); + maketojumpbool(exprasmlist,left,lr_load_regvars); + hl:=truelabel; + truelabel:=falselabel; + falselabel:=hl; + end + else + begin + { the second pass could change the location of left } + { if it is a register variable, so we've to do } + { this before the case statement } + secondpass(left); + case left.expectloc of + LOC_FLAGS : + begin + location_release(exprasmlist,left.location); + location_reset(location,LOC_FLAGS,OS_NO); + location.resflags:=left.location.resflags; + inverse_flags(location.resflags); end; - end; - end -{$ifdef SUPPORT_MMX} - else - if (cs_mmx in aktlocalswitches) and is_mmx_able_array(left.resulttype.def) then - begin - secondpass(left); - location_reset(location,LOC_MMXREGISTER,OS_NO); - { prepare EDI } - r.enum:=R_INTREGISTER; - r.number:=NR_EDI; - r2.enum:=R_MM7; - rg.getexplicitregisterint(exprasmlist,NR_EDI); - emit_const_reg(A_MOV,S_L,longint($ffffffff),r); - { load operand } - case left.location.loc of - LOC_MMXREGISTER: - location_copy(location,left.location); - LOC_CMMXREGISTER: - begin - location.register:=rg.getregistermm(exprasmlist); - emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register); - end; - LOC_REFERENCE, - LOC_CREFERENCE: - begin - location_release(exprasmlist,left.location); - location.register:=rg.getregistermm(exprasmlist); - emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register); - end; - end; - { load mask } - emit_reg_reg(A_MOVD,S_NO,r,r2); - rg.ungetregisterint(exprasmlist,r); - { lower 32 bit } - emit_reg_reg(A_PXOR,S_D,r2,location.register); - { shift mask } - emit_const_reg(A_PSLLQ,S_NO,32,r2); - { higher 32 bit } - emit_reg_reg(A_PXOR,S_D,r2,location.register); - end -{$endif SUPPORT_MMX} - else if is_64bitint(left.resulttype.def) then - begin - secondpass(left); - location_copy(location,left.location); - location_force_reg(exprasmlist,location,OS_64,false); - - emit_reg(A_NOT,S_L,location.registerlow); - emit_reg(A_NOT,S_L,location.registerhigh); - end - else - begin - secondpass(left); - location_copy(location,left.location); - location_force_reg(exprasmlist,location,def_cgsize(resulttype.def),false); - - opsize:=def_opsize(resulttype.def); - emit_reg(A_NOT,opsize,location.register); - end; + LOC_CONSTANT, + LOC_REGISTER, + LOC_CREGISTER, + LOC_REFERENCE, + LOC_CREFERENCE : + begin + location_force_reg(exprasmlist,left.location,def_cgsize(resulttype.def),true); + emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register); + location_release(exprasmlist,left.location); + location_reset(location,LOC_FLAGS,OS_NO); + location.resflags:=F_E; + end; + else + internalerror(200203224); + end; + end; end; +{$ifdef SUPPORT_MMX} + procedure ti386notnode.second_mmx; + var + r,r2 : tregister; + begin + secondpass(left); + location_reset(location,LOC_MMXREGISTER,OS_NO); + { prepare EDI } + r.enum:=R_INTREGISTER; + r.number:=NR_EDI; + r2.enum:=R_MM7; + rg.getexplicitregisterint(exprasmlist,NR_EDI); + emit_const_reg(A_MOV,S_L,longint($ffffffff),r); + { load operand } + case left.location.loc of + LOC_MMXREGISTER: + location_copy(location,left.location); + LOC_CMMXREGISTER: + begin + location.register:=rg.getregistermm(exprasmlist); + emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register); + end; + LOC_REFERENCE, + LOC_CREFERENCE: + begin + location_release(exprasmlist,left.location); + location.register:=rg.getregistermm(exprasmlist); + emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register); + end; + end; + { load mask } + emit_reg_reg(A_MOVD,S_NO,r,r2); + rg.ungetregisterint(exprasmlist,r); + { lower 32 bit } + emit_reg_reg(A_PXOR,S_D,r2,location.register); + { shift mask } + emit_const_reg(A_PSLLQ,S_NO,32,r2); + { higher 32 bit } + emit_reg_reg(A_PXOR,S_D,r2,location.register); + end; +{$endif SUPPORT_MMX} + begin cmoddivnode:=ti386moddivnode; cshlshrnode:=ti386shlshrnode; @@ -1173,7 +1094,12 @@ begin end. { $Log$ - Revision 1.56 2003-06-03 13:01:59 daniel + Revision 1.57 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.56 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.55 2003/05/31 15:04:31 peter diff --git a/compiler/i386/n386obj.pas b/compiler/i386/n386obj.pas index ff20e8ced3..8d4a975c90 100644 --- a/compiler/i386/n386obj.pas +++ b/compiler/i386/n386obj.pas @@ -117,7 +117,7 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef r.number:=NR_ESP; reference_reset_base(href,r,getselfoffsetfromsp(procdef)); r.number:=NR_EAX; - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,r); end; procedure loadvmttoeax; @@ -247,7 +247,12 @@ initialization end. { $Log$ - Revision 1.19 2003-05-15 18:58:54 peter + Revision 1.20 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.19 2003/05/15 18:58:54 peter * removed selfpointer_offset, vmtpointer_offset * tvarsym.adjusted_address * address in localsymtable is now in the real direction diff --git a/compiler/i386/n386set.pas b/compiler/i386/n386set.pas index 8a0ae12ec7..f958acd9db 100644 --- a/compiler/i386/n386set.pas +++ b/compiler/i386/n386set.pas @@ -413,8 +413,7 @@ implementation LOC_REGISTER, LOC_CREGISTER: begin - hr.enum:=R_INTREGISTER; - hr.number:=(left.location.register.number and not $ff) or R_SUBWHOLE; + hr:=rg.makeregsize(left.location.register,OS_INT); cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr); end; else @@ -619,14 +618,13 @@ implementation if not(jumptable_no_range) then begin { case expr less than min_ => goto elselabel } - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,aword(min_),hregister,elselabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aword(min_),hregister,elselabel); { case expr greater than max_ => goto elselabel } - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,aword(max_),hregister,elselabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_gt,aword(max_),hregister,elselabel); end; objectlibrary.getlabel(table); { make it a 32bit register } - indexreg.enum:=R_INTREGISTER; - indexreg.number:=(hregister.number and not $ff) or R_SUBWHOLE; + indexreg:=rg.makeregsize(hregister,OS_INT); cg.a_load_reg_reg(exprasmlist,opsize,OS_INT,hregister,indexreg); { create reference } reference_reset_symbol(href,table,0); @@ -657,15 +655,15 @@ implementation { need we to test the first value } if first and (t^._low>get_min_value(left.resulttype.def)) then begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,aword(t^._low),hregister,elselabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aword(t^._low),hregister,elselabel); end; if t^._low=t^._high then begin if t^._low-last=0 then - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement) + cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,0,hregister,t^.statement) else begin - cg.a_op_const_reg(exprasmlist, OP_SUB, OS_INT, aword(t^._low-last), hregister); + cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, aword(t^._low-last), hregister); emitjmp(C_Z,t^.statement); end; last:=t^._low; @@ -680,7 +678,7 @@ implementation begin { have we to ajust the first value ? } if (t^._low>get_min_value(left.resulttype.def)) then - cg.a_op_const_reg(exprasmlist, OP_SUB, OS_INT, longint(t^._low), hregister); + cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, longint(t^._low), hregister); end else begin @@ -688,7 +686,7 @@ implementation { present label then the lower limit can be checked } { immediately. else check the range in between: } - cg.a_op_const_reg(exprasmlist, OP_SUB, OS_INT, longint(t^._low-last), hregister); + cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, longint(t^._low-last), hregister); { no jump necessary here if the new range starts at } { at the value following the previous one } if ((t^._low-last) <> 1) or @@ -739,7 +737,12 @@ begin end. { $Log$ - Revision 1.60 2003-06-01 21:38:06 peter + Revision 1.61 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.60 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/i386/rgcpu.pas b/compiler/i386/rgcpu.pas index dd446ab5a0..6031c35391 100644 --- a/compiler/i386/rgcpu.pas +++ b/compiler/i386/rgcpu.pas @@ -110,68 +110,6 @@ unit rgcpu; globals,verbose, tgobj; -{************************************************************************} -{ routine helpers } -{************************************************************************} - const - reg2reg32 : array[firstreg..lastreg] of Toldregister = (R_NO, - R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI, - R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI, - R_EAX,R_ECX,R_EDX,R_EBX,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO - ); - reg2reg16 : array[firstreg..lastreg] of Toldregister = (R_NO, - R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI, - R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI, - R_AX,R_CX,R_DX,R_BX,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO - ); - reg2reg8 : array[firstreg..lastreg] of Toldregister = (R_NO, - R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO, - R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO, - R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO, - R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO - ); - - { convert a register to a specfied register size } - function changeregsize(r:tregister;size:topsize):tregister; - var - reg : tregister; - begin - case size of - S_B : - reg.enum:=reg2reg8[r.enum]; - S_W : - reg.enum:=reg2reg16[r.enum]; - S_L : - reg.enum:=reg2reg32[r.enum]; - else - internalerror(200204101); - end; - if reg.enum=R_NO then - internalerror(200204102); - changeregsize:=reg; - end; - - {************************************************************************} { trgcpu } {************************************************************************} @@ -564,27 +502,11 @@ unit rgcpu; function trgcpu.makeregsize(reg: tregister; size: tcgsize): tregister; - - var - _result : topsize; begin - case size of - OS_32,OS_S32: - begin - _result := S_L; - end; - OS_8,OS_S8: - begin - _result := S_B; - end; - OS_16,OS_S16: - begin - _result := S_W; - end; - else - internalerror(2001092312); - end; - makeregsize := changeregsize(reg,_result); + if reg.enum<>R_INTREGISTER then + internalerror(200306032); + result.enum:=R_INTREGISTER; + result.number:=(reg.number and (not $ff)) or cgsize2subreg(size); end; @@ -595,7 +517,12 @@ end. { $Log$ - Revision 1.24 2003-06-03 13:01:59 daniel + Revision 1.25 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.24 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.23 2003/06/01 21:38:06 peter diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index d9805694a8..fbfe5dcdd3 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -166,7 +166,7 @@ implementation {$endif} cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg); reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href); {$ifdef newra} rg.ungetregisterint(exprasmlist,tmpreg); {$else} @@ -205,7 +205,7 @@ implementation if calloption=pocall_inline then begin reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize); - cg.a_load_loc_ref(exprasmlist,left.location,href); + cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,href); end else cg.a_param_loc(exprasmlist,left.location,paraitem.paraloc); @@ -225,7 +225,7 @@ implementation {$endif newra} cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg); reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href); {$ifdef newra} rg.ungetregisterint(exprasmlist,tmpreg); {$else} @@ -263,7 +263,7 @@ implementation {$endif} cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg); reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href); {$ifdef newra} rg.ungetregisterint(exprasmlist,tmpreg); {$else} @@ -293,7 +293,7 @@ implementation begin tg.GetTemp(exprasmlist,tcgsize2size[left.location.size],tt_normal,href); if not (left.location.size in [OS_64,OS_S64]) then - cg.a_load_loc_ref(exprasmlist,left.location,href) + cg.a_load_loc_ref(exprasmlist,left.location.size,left.location,href) else cg64.a_load64_loc_ref(exprasmlist,left.location,href); location_reset(left.location,LOC_REFERENCE,left.location.size); @@ -313,7 +313,7 @@ implementation {$endif} cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg); reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href); {$ifdef newra} rg.ungetregisterint(exprasmlist,tmpreg); {$else} @@ -391,12 +391,12 @@ implementation begin hregister:=rg.getaddressregister(exprasmlist); reference_reset_base(href,current_procinfo.framepointer,current_procinfo.framepointer_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); i:=current_procdef.parast.symtablelevel; while (i>tprocdef(procdefinition).parast.symtablelevel) do begin reference_reset_base(href,hregister,current_procinfo.framepointer_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); dec(i); end; cg.a_param_reg(exprasmlist,OS_ADDR,hregister,paramanager.getintparaloc(1)); @@ -409,7 +409,6 @@ implementation var cgsize : tcgsize; r,hregister : tregister; - nr:Tnewregister; begin { structured results are easy to handle.... } { needed also when result_no_used !! } @@ -429,7 +428,7 @@ implementation r.enum:=R_INTREGISTER; r.number:=NR_FUNCTION_RETURN_REG; cg.a_reg_alloc(exprasmlist,r); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,r,location.reference); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,location.reference); cg.a_reg_dealloc(exprasmlist,r); end else @@ -504,9 +503,9 @@ implementation begin {Move the function result to a free register, preferably the FUNCTION_RESULT_REG, so no move is necessary.} - nr:=(RS_FUNCTION_RESULT_REG shl 8) or cgsize2subreg(cgsize); r.enum:=R_INTREGISTER; - r.number:=nr; + r.number:=NR_FUNCTION_RESULT_REG; + r:=rg.makeregsize(r,cgsize); {$ifdef newra} { rg.getexplicitregisterint(exprasmlist,nr);} rg.ungetregisterint(exprasmlist,r); @@ -514,7 +513,10 @@ implementation {$else newra} cg.a_reg_alloc(exprasmlist,r); if RS_FUNCTION_RESULT_REG in rg.unusedregsint then - location.register:=rg.getexplicitregisterint(exprasmlist,nr) + begin + location.register:=rg.makeregsize(rg.getexplicitregisterint( + exprasmlist,NR_FUNCTION_RESULT_REG),cgsize); + end else location.register:=rg.getregisterint(exprasmlist,cgsize); {$endif newra} @@ -858,7 +860,7 @@ implementation end else rg.ungetregisterint(exprasmlist,right.location.register); - + reference_release(exprasmlist,helpref); location_freetemp(exprasmlist,right.location); for i:=first_supreg to last_supreg do @@ -1378,7 +1380,12 @@ begin end. { $Log$ - Revision 1.83 2003-06-03 20:27:02 daniel + Revision 1.84 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.83 2003/06/03 20:27:02 daniel * Restored original methodpointer code for non newra case Revision 1.82 2003/06/03 13:01:59 daniel diff --git a/compiler/ncgcnv.pas b/compiler/ncgcnv.pas index 855bedd7f9..b3e96c2e76 100644 --- a/compiler/ncgcnv.pas +++ b/compiler/ncgcnv.pas @@ -83,7 +83,7 @@ interface { insert range check if not explicit conversion } if not(nf_explicit in flags) then - cg.g_rangecheck(exprasmlist,left,resulttype.def); + cg.g_rangecheck(exprasmlist,left.location,left.resulttype.def,resulttype.def); { is the result size smaller? when typecasting from void we always reuse the current location, because there is @@ -143,7 +143,7 @@ interface else begin location.register:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.register); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.register); end; end; st_longstring: @@ -167,7 +167,7 @@ interface {$ifdef fpc} {$warning Todo: convert widestrings to ascii when typecasting them to pchars} {$endif} - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference, + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_INT,left.location.reference, location.register); end; end; @@ -236,7 +236,7 @@ interface begin location_release(exprasmlist,left.location); location.reference.base:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference, + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference, location.reference.base); location_freetemp(exprasmlist,left.location); end; @@ -253,7 +253,7 @@ interface st_shortstring : begin tg.GetTemp(exprasmlist,256,tt_normal,location.reference); - cg.a_load_loc_ref(exprasmlist,left.location, + cg.a_load_loc_ref(exprasmlist,left.location.size,left.location, location.reference); location_release(exprasmlist,left.location); location_freetemp(exprasmlist,left.location); @@ -377,7 +377,7 @@ interface begin location_release(exprasmlist,left.location); location.register:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,location.register); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.register); location_freetemp(exprasmlist,left.location); end; else @@ -403,7 +403,7 @@ interface begin location_release(exprasmlist,left.location); location.register:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.register); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.register); location_freetemp(exprasmlist,left.location); end; LOC_CREGISTER: @@ -510,7 +510,12 @@ end. { $Log$ - Revision 1.43 2003-06-01 21:38:06 peter + Revision 1.44 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.43 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index 255aea4b15..62cc9caa4a 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -391,8 +391,7 @@ implementation if (right.location.loc=LOC_REGISTER) or (right.location.loc=LOC_CREGISTER) then begin - cg.a_load_reg_ref(exprasmlist,opsize, - right.location.register,temp1); + cg.a_load_reg_ref(exprasmlist,opsize,opsize,right.location.register,temp1); rg.ungetregisterint(exprasmlist,right.location.register); end else @@ -1156,8 +1155,7 @@ implementation { what a hack ! } if assigned(exceptsymtable) then tvarsym(exceptsymtable.symindex.first).address:=ref.offset; - cg.a_load_reg_ref(exprasmlist, OS_ADDR, r, ref); - + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,ref); { in the case that another exception is risen } { we've to destroy the old one } @@ -1421,7 +1419,12 @@ begin end. { $Log$ - Revision 1.67 2003-06-01 21:38:06 peter + Revision 1.68 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.67 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/ncginl.pas b/compiler/ncginl.pas index e18200182b..2e0191a3b2 100644 --- a/compiler/ncginl.pas +++ b/compiler/ncginl.pas @@ -251,7 +251,7 @@ implementation begin { load VMT pointer } reference_reset_base(hrefvmt,left.location.register,tobjectdef(left.resulttype.def).vmt_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,hrefvmt,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister); end end; LOC_REFERENCE, @@ -260,18 +260,18 @@ implementation if is_class(left.resulttype.def) then begin { deref class } - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister); cg.g_maybe_testself(exprasmlist,hregister); { load VMT pointer } reference_reset_base(hrefvmt,hregister,tobjectdef(left.resulttype.def).vmt_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,hrefvmt,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister); end else begin { load VMT pointer, but not for classrefdefs } if (left.resulttype.def.deftype=objectdef) then inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister); end; end; else @@ -284,7 +284,7 @@ implementation reference_reset_base(href,hregister,0); rg.ungetaddressregister(exprasmlist,hregister); hregister:=rg.getregisterint(exprasmlist,OS_INT); - cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister); end; location.register:=hregister; end; @@ -315,7 +315,7 @@ implementation objectlibrary.getlabel(lengthlab); cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,lengthlab); reference_reset_base(href,hregister,-8); - cg.a_load_ref_reg(exprasmlist,OS_32,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister); cg.a_label(exprasmlist,lengthlab); location_reset(location,LOC_REGISTER,OS_32); location.register:=hregister; @@ -349,7 +349,7 @@ implementation else cg.a_op_const_reg(exprasmlist,cgop,location.size,1,location.register); - cg.g_rangecheck(exprasmlist,self,resulttype.def); + cg.g_rangecheck(exprasmlist,location,resulttype.def,resulttype.def); end; @@ -435,8 +435,9 @@ implementation location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location); end; location_release(exprasmlist,tcallparanode(left).left.location); - cg.g_overflowcheck(exprasmlist,tcallparanode(left).left); - cg.g_rangecheck(exprasmlist,tcallparanode(left).left,tcallparanode(left).left.resulttype.def); + cg.g_overflowcheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).resulttype.def); + cg.g_rangecheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).left.resulttype.def, + tcallparanode(left).left.resulttype.def); end; @@ -536,7 +537,7 @@ implementation LOC_REFERENCE: begin cgsize := def_cgsize(tcallparanode(tcallparanode(left).right).left.resulttype.def); - cg.a_load_ref_reg(exprasmlist,cgsize, + cg.a_load_ref_reg(exprasmlist,cgsize,cgsize, tcallparanode(tcallparanode(left).right).left.location.reference,hregister); end; else @@ -681,7 +682,12 @@ end. { $Log$ - Revision 1.34 2003-06-01 21:38:06 peter + Revision 1.35 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.34 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index bfc1fb0658..b2d8fa0498 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -119,7 +119,7 @@ implementation begin hregister:=rg.getaddressregister(exprasmlist); location.reference.symbol:=objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,location.reference,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,location.reference,hregister); reference_reset_base(location.reference,hregister,0); end { external variable } @@ -135,7 +135,7 @@ implementation { we've to allocate the register before we save the used registers } hregister:=rg.getaddressregister(exprasmlist); reference_reset_symbol(href,objectlibrary.newasmsymboldata('FPC_THREADVAR_RELOCATE'),0); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_NE,0,hregister,dorelocatelab); { no relocation needed, load the address of the variable only, the layout of a threadvar is (4 bytes pointer): @@ -189,7 +189,7 @@ implementation if (supreg in general_superregisters) and not (supreg in rg.regvar_loaded_int) then load_regvar(exprasmlist,tvarsym(symtableentry)); - location_reset(location,LOC_CREGISTER,cg.reg_cgsize(tvarsym(symtableentry).reg)); + location_reset(location,LOC_CREGISTER,def_cgsize(resulttype.def)); location.register:=tvarsym(symtableentry).reg; exclude(rg.unusedregsint,supreg); end @@ -212,7 +212,7 @@ implementation hregister:=rg.getaddressregister(exprasmlist); { make a reference } reference_reset_base(href,current_procinfo.framepointer,current_procinfo.framepointer_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); { walk parents } i:=current_procdef.parast.symtablelevel-1; while (i>symtable.symtablelevel) do @@ -223,7 +223,7 @@ implementation {$else powerpc} reference_reset_base(href,hregister,target_info.first_parm_offset); {$endif powerpc} - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); dec(i); end; location.reference.base:=hregister; @@ -298,7 +298,7 @@ implementation begin hregister:=rg.getaddressregister(exprasmlist); if is_class_or_interface(left.resulttype.def) then - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister) + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister) else cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister); location_release(exprasmlist,left.location); @@ -311,7 +311,7 @@ implementation { store the class instance address } href:=location.reference; inc(href.offset,POINTER_SIZE); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,hregister,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,href); { virtual method ? } if (po_virtualmethod in procdef.procoptions) then @@ -320,7 +320,7 @@ implementation reference_reset_base(href,hregister,0); reference_release(exprasmlist,href); hregister:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); reference_reset_base(href,hregister, @@ -329,9 +329,9 @@ implementation { load method address } hregister:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,hregister); { ... and store it } - cg.a_load_reg_ref(exprasmlist,OS_ADDR,hregister,location.reference); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,location.reference); rg.ungetaddressregister(exprasmlist,hregister); end else @@ -346,7 +346,7 @@ implementation hregister:=cg.get_scratch_reg_address(exprasmlist); {$endif} cg.a_loadaddr_ref_reg(exprasmlist,href,hregister); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,hregister,location.reference); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,location.reference); {$ifdef newra} rg.ungetregisterint(exprasmlist,hregister); {$else newra} @@ -517,13 +517,12 @@ implementation LOC_REGISTER, LOC_CREGISTER : begin - r.enum:=R_INTREGISTER; - r.number:=(right.location.register.number and not $ff) or R_SUBL; - cg.a_load_reg_ref(exprasmlist,OS_8,r,href); + r:=rg.makeregsize(right.location.register,OS_8); + cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,r,href); end; LOC_REFERENCE, LOC_CREFERENCE : - cg.a_load_ref_ref(exprasmlist,OS_8,right.location.reference,href); + cg.a_load_ref_ref(exprasmlist,OS_8,OS_8,right.location.reference,href); else internalerror(200205111); end; @@ -554,7 +553,7 @@ implementation cg64.a_load64_ref_reg(exprasmlist, right.location.reference,left.location.register64{$ifdef newra},false{$endif}) else - cg.a_load_ref_reg(exprasmlist,cgsize, + cg.a_load_ref_reg(exprasmlist,cgsize,cgsize, right.location.reference,left.location.register); location_release(exprasmlist,right.location); end; @@ -870,7 +869,7 @@ implementation tmpreg:=cg.get_scratch_reg_address(exprasmlist); {$endif} cg.a_loadaddr_ref_reg(exprasmlist,hp.left.location.reference,tmpreg); - cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href); + cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,tmpreg,href); {$ifdef newra} rg.ungetregisterint(exprasmlist,tmpreg); {$else} @@ -883,7 +882,7 @@ implementation else begin location_release(exprasmlist,hp.left.location); - cg.a_load_loc_ref(exprasmlist,hp.left.location,href); + cg.a_load_loc_ref(exprasmlist,OS_ADDR,hp.left.location,href); end; { update href to the vtype field and write it } dec(href.offset,4); @@ -917,7 +916,7 @@ implementation if hp.left.location.size in [OS_64,OS_S64] then cg64.a_load64_loc_ref(exprasmlist,hp.left.location,href) else - cg.a_load_loc_ref(exprasmlist,hp.left.location,href); + cg.a_load_loc_ref(exprasmlist,hp.left.location.size,hp.left.location,href); end; end; inc(href.offset,elesize); @@ -935,7 +934,12 @@ begin end. { $Log$ - Revision 1.65 2003-06-03 13:01:59 daniel + Revision 1.66 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.65 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.64 2003/05/30 23:57:08 peter diff --git a/compiler/ncgmat.pas b/compiler/ncgmat.pas index a85b84a9f3..5b8acf92c9 100644 --- a/compiler/ncgmat.pas +++ b/compiler/ncgmat.pas @@ -31,7 +31,6 @@ interface type tcgunaryminusnode = class(tunaryminusnode) - procedure pass_2;override; protected { This routine is called to change the sign of the floating point value in the floating point @@ -44,6 +43,14 @@ type in IEEE-754 format. } procedure emit_float_sign_change(r: tregister; _size : tcgsize);virtual; +{$ifdef SUPPORT_MMX} + procedure second_mmx;virtual;abstract; +{$endif SUPPORT_MMX} + procedure second_64bit;virtual; + procedure second_integer;virtual; + procedure second_float;virtual; + public + procedure pass_2;override; end; tcgmoddivnode = class(tmoddivnode) @@ -96,6 +103,10 @@ type tcgnotnode = class(tnotnode) protected procedure second_boolean;virtual;abstract; +{$ifdef SUPPORT_MMX} + procedure second_mmx;virtual;abstract; +{$endif SUPPORT_MMX} + procedure second_64bit;virtual; procedure second_integer;virtual; public procedure pass_2;override; @@ -116,10 +127,11 @@ implementation {***************************************************************************** TCGUNARYMINUSNODE *****************************************************************************} + procedure tcgunaryminusnode.emit_float_sign_change(r: tregister; _size : tcgsize); - var - href : treference; - hreg : tregister; + var + href : treference; + hreg : tregister; begin { get a temporary memory reference to store the floating point value @@ -141,7 +153,7 @@ implementation internalerror(20020814); hreg := rg.getregisterint(exprasmlist,OS_32); { load value } - cg.a_load_ref_reg(exprasmlist,OS_32,href,hreg); + cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hreg); { bitwise complement copied value } cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_32,hreg,hreg); { sign-bit is bit 31/63 of single/double } @@ -162,81 +174,73 @@ implementation end; + procedure tcgunaryminusnode.second_64bit; + begin + secondpass(left); + { load left operator in a register } + location_copy(location,left.location); + location_force_reg(exprasmlist,location,OS_64,false); + cg64.a_op64_loc_reg(exprasmlist,OP_NEG, + location,joinreg64(location.registerlow,location.registerhigh)); + end; + + + procedure tcgunaryminusnode.second_float; + begin + secondpass(left); + location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); + case left.location.loc of + LOC_REFERENCE, + LOC_CREFERENCE : + begin + reference_release(exprasmlist,left.location.reference); + location.register:=rg.getregisterfpu(exprasmlist,location.size); + cg.a_loadfpu_ref_reg(exprasmlist, + def_cgsize(left.resulttype.def), + left.location.reference,location.register); + emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); + end; + LOC_FPUREGISTER: + begin + location.register:=left.location.register; + emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); + end; + LOC_CFPUREGISTER: + begin + location.register:=rg.getregisterfpu(exprasmlist,location.size); + cg.a_loadfpu_reg_reg(exprasmlist,left.location.register,location.register); + emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); + end; + else + internalerror(200306021); + end; + end; + + + procedure tcgunaryminusnode.second_integer; + begin + secondpass(left); + { load left operator in a register } + location_copy(location,left.location); + location_force_reg(exprasmlist,location,OS_INT,false); + cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register,location.register); + end; + + procedure tcgunaryminusnode.pass_2; - - begin if is_64bit(left.resulttype.def) then - begin - secondpass(left); - - { load left operator in a register } - location_copy(location,left.location); - location_force_reg(exprasmlist,location,OS_64,false); - cg64.a_op64_loc_reg(exprasmlist,OP_NEG, - location,joinreg64(location.registerlow,location.registerhigh)); - end + second_64bit +{$ifdef SUPPORT_MMX} else - begin - secondpass(left); - location_reset(location,LOC_REGISTER,OS_INT); - case left.location.loc of - LOC_REGISTER: - begin - location.register:=left.location.register; - cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register, - location.register); - end; - LOC_CREGISTER: - begin - location.register:=rg.getregisterint(exprasmlist,OS_INT); - cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,left.location.register, - location.register); - cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register, - location.register); - end; - LOC_REFERENCE, - LOC_CREFERENCE: - begin - reference_release(exprasmlist,left.location.reference); - if (left.resulttype.def.deftype=floatdef) then - begin - location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); - location.register:=rg.getregisterfpu(exprasmlist,location.size); - cg.a_loadfpu_ref_reg(exprasmlist, - def_cgsize(left.resulttype.def), - left.location.reference,location.register); - emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); - end - else - begin - location.register:=rg.getregisterint(exprasmlist,OS_INT); - { why is the size is OS_INT, since in pass_1 we convert - everything to a signed natural value anyways - } - cg.a_load_ref_reg(exprasmlist,OS_INT, - left.location.reference,location.register); - cg.a_op_reg_reg(exprasmlist,OP_NEG,OS_INT,location.register, - location.register); - end; - end; - LOC_FPUREGISTER: - begin - location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); - location.register:=left.location.register; - emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); - end; - LOC_CFPUREGISTER: - begin - location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); - location.register:=rg.getregisterfpu(exprasmlist,location.size); - cg.a_loadfpu_reg_reg(exprasmlist,left.location.register,location.register); - emit_float_sign_change(location.register,def_cgsize(left.resulttype.def)); - end; - else - internalerror(200203225); - end; - end; + if (cs_mmx in aktlocalswitches) and is_mmx_able_array(left.resulttype.def) then + second_mmx +{$endif SUPPORT_MMX} + else + if (left.resulttype.def.deftype=floatdef) then + second_float + else + second_integer; end; @@ -341,7 +345,7 @@ implementation location_reset(location,LOC_REGISTER,OS_INT); location.register:=hreg1; end; - cg.g_overflowcheck(exprasmlist,self); + cg.g_overflowcheck(exprasmlist,location,resulttype.def); end; @@ -468,24 +472,23 @@ implementation TCGNOTNODE *****************************************************************************} + procedure tcgnotnode.second_64bit; + begin + secondpass(left); + location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false); + location_copy(location,left.location); + { perform the NOT operation } + cg64.a_op64_reg_reg(exprasmlist,OP_NOT,left.location.register64,location.register64); + end; + + procedure tcgnotnode.second_integer; begin - if is_64bit(left.resulttype.def) then - begin - secondpass(left); - location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false); - location_copy(location,left.location); - { perform the NOT operation } - cg64.a_op64_reg_reg(exprasmlist,OP_NOT,left.location.register64,location.register64); - end - else - begin - secondpass(left); - location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false); - location_copy(location,left.location); - { perform the NOT operation } - cg.a_op_reg_reg(exprasmlist,OP_NOT,location.size,location.register,location.register); - end; + secondpass(left); + location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false); + location_copy(location,left.location); + { perform the NOT operation } + cg.a_op_reg_reg(exprasmlist,OP_NOT,location.size,location.register,location.register); end; @@ -493,6 +496,12 @@ implementation begin if is_boolean(resulttype.def) then second_boolean +{$ifdef SUPPORT_MMX} + else if (cs_mmx in aktlocalswitches) and is_mmx_able_array(left.resulttype.def) then + second_mmx +{$endif SUPPORT_MMX} + else if is_64bit(left.resulttype.def) then + second_64bit else second_integer; end; @@ -505,7 +514,12 @@ begin end. { $Log$ - Revision 1.12 2003-06-01 21:38:06 peter + Revision 1.13 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.12 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 2f0735cc97..e13c2f1a4b 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -154,7 +154,7 @@ implementation reference_release(exprasmlist,href); location.register:=rg.getaddressregister(exprasmlist); cg.g_maybe_testself(exprasmlist,href.base); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,location.register); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,location.register); end else begin @@ -195,7 +195,7 @@ implementation assigned(tloadnode(left).symtableentry) and (tloadnode(left).symtableentry.typ=varsym) and (tvarsym(tloadnode(left).symtableentry).vartype.def.deftype=procvardef) then - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference, + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference, location.register) else begin @@ -312,7 +312,7 @@ implementation else if is_interfacecom(left.resulttype.def) then begin tg.GetTemp(exprasmlist,pointer_size,tt_interfacecom,location.reference); - cg.a_load_loc_ref(exprasmlist,left.location,location.reference); + cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,location.reference); { implicit deferencing also for interfaces } if (cs_gdb_heaptrc in aktglobalswitches) and (cs_checkpointer in aktglobalswitches) and @@ -538,7 +538,7 @@ implementation {$endif} end else - cg.g_rangecheck(exprasmlist,right,left.resulttype.def); + cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def); end; @@ -611,8 +611,8 @@ implementation LOC_REFERENCE : begin location_release(exprasmlist,left.location); - location.reference.base:=rg.getregisterint(exprasmlist,OS_INT); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,location.reference.base); + location.reference.base:=rg.getaddressregister(exprasmlist); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,location.reference.base); end; else internalerror(2002032218); @@ -667,7 +667,7 @@ implementation begin location_release(exprasmlist,left.location); location.reference.base:=rg.getaddressregister(exprasmlist); - cg.a_load_ref_reg(exprasmlist,OS_ADDR, + cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR, left.location.reference,location.reference.base); end; else @@ -937,7 +937,12 @@ begin end. { $Log$ - Revision 1.58 2003-06-03 13:01:59 daniel + Revision 1.59 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.58 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.57 2003/06/02 22:35:45 florian diff --git a/compiler/ncgopt.pas b/compiler/ncgopt.pas index e98111731d..25447d9fb6 100644 --- a/compiler/ncgopt.pas +++ b/compiler/ncgopt.pas @@ -122,7 +122,7 @@ begin reference_release(exprasmlist,right.location.reference); { get register for the char } hreg := rg.getregisterint(exprasmlist,OS_8); - cg.a_load_ref_reg(exprasmlist,OS_8,right.location.reference,hreg); + cg.a_load_ref_reg(exprasmlist,OS_8,OS_8,right.location.reference,hreg); { I don't think a temp char exists, but it won't hurt (JM) } tg.ungetiftemp(exprasmlist,right.location.reference); end @@ -130,7 +130,7 @@ begin { load the current string length } lengthreg := rg.getregisterint(exprasmlist,OS_INT); - cg.a_load_ref_reg(exprasmlist,OS_8,left.location.reference,lengthreg); + cg.a_load_ref_reg(exprasmlist,OS_8,OS_INT,left.location.reference,lengthreg); { do we have to check the length ? } if tg.istemp(left.location.reference) then @@ -181,7 +181,7 @@ begin begin { no new_reference(href2) because it's only } { used once (JM) } - cg.a_load_reg_ref(exprasmlist,OS_8,hreg,href2); + cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,hreg,href2); rg.ungetregisterint(exprasmlist,hreg); end else @@ -189,7 +189,7 @@ begin lengthreg.number:=(lengthreg.number and not $ff) or R_SUBL; { increase the string length } cg.a_op_const_reg(exprasmlist,OP_ADD,OS_8,1,lengthreg); - cg.a_load_reg_ref(exprasmlist,OS_8,lengthreg,left.location.reference); + cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,lengthreg,left.location.reference); rg.ungetregisterint(exprasmlist,lengthreg); if checklength then cg.a_label(exprasmlist,l); @@ -202,7 +202,12 @@ end. { $Log$ - Revision 1.5 2003-06-03 13:01:59 daniel + Revision 1.6 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.5 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.4 2003/06/01 21:38:06 peter diff --git a/compiler/ncgset.pas b/compiler/ncgset.pas index 0930a755b5..819ed9609b 100644 --- a/compiler/ncgset.pas +++ b/compiler/ncgset.pas @@ -283,7 +283,7 @@ implementation { location is always LOC_JUMP } location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def)); { allocate a register for the result } - location.register := rg.getregisterint(exprasmlist,OS_INT); + location.register := rg.getregisterint(exprasmlist,location.size); if genjumps then begin @@ -291,7 +291,7 @@ implementation objectlibrary.getlabel(l); { clear the register value, indicating result is FALSE } - cg.a_load_const_reg(exprasmlist,OS_INT,0,location.register); + cg.a_load_const_reg(exprasmlist,location.size,0,location.register); opsize := def_cgsize(left.resulttype.def); { If register is used, use only lower 8 bits } if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then @@ -317,13 +317,13 @@ implementation else begin { load the value in a register } - {$ifdef newra} - pleftreg:=rg.getregisterint(exprasmlist,OS_INT); - {$else} - pleftreg := cg.get_scratch_reg_int(exprasmlist,OS_INT); - {$endif} opsize := OS_INT; - cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),left.location.reference,pleftreg); + {$ifdef newra} + pleftreg:=rg.getregisterint(exprasmlist,opsize); + {$else} + pleftreg := cg.get_scratch_reg_int(exprasmlist,opsize); + {$endif} + cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),opsize,left.location.reference,pleftreg); end; @@ -362,7 +362,7 @@ implementation begin { otherwise, the value is already in a register } { that can be modified } - cg.a_op_const_reg(exprasmlist,OP_SUB,OS_INT, + cg.a_op_const_reg(exprasmlist,OP_SUB,opsize, setparts[i].start-adjustment,pleftreg) end; { new total value substracted from x: } @@ -396,7 +396,7 @@ implementation { Now place the end label if IN success } cg.a_label(exprasmlist,l); { result register is 1 } - cg.a_load_const_reg(exprasmlist,OS_INT,1,location.register); + cg.a_load_const_reg(exprasmlist,location.size,1,location.register); { in case value is not found } cg.a_label(exprasmlist,l3); case left.location.loc of @@ -432,7 +432,7 @@ implementation if left.nodetype=ordconstn then begin { clear the register value, indicating result is FALSE } - cg.a_load_const_reg(exprasmlist,OS_INT,0,location.register); + cg.a_load_const_reg(exprasmlist,location.size,0,location.register); case right.location.loc of LOC_REGISTER: hr:=right.location.register; @@ -440,7 +440,7 @@ implementation begin hr:=rg.getregisterint(exprasmlist,OS_INT); { load set value into register } - cg.a_load_reg_reg(exprasmlist,OS_32,OS_32, + cg.a_load_reg_reg(exprasmlist,right.location.size,OS_INT, right.location.register,hr); location_release(exprasmlist,right.location); end; @@ -449,7 +449,7 @@ implementation begin hr:=rg.getregisterint(exprasmlist,OS_INT); { load set value into register } - cg.a_load_ref_reg(exprasmlist,OS_32, + cg.a_load_ref_reg(exprasmlist,OS_INT,opsize, right.location.reference,hr); location_release(exprasmlist,right.location); end; @@ -470,8 +470,7 @@ implementation LOC_REGISTER, LOC_CREGISTER: begin - hr3.enum:=R_INTREGISTER; - hr3.number:=(left.location.register.number and not $ff) or R_SUBWHOLE; + hr3:=rg.makeregsize(left.location.register,OS_INT); cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,hr3); {$ifdef newra} hr:=rg.getregisterint(exprasmlist,OS_INT); @@ -487,34 +486,30 @@ implementation {$else} hr:=cg.get_scratch_reg_int(exprasmlist,OS_INT); {$endif} - cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def), + cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),OS_INT, left.location.reference,hr); location_release(exprasmlist,left.location); end; end; case right.location.loc of - LOC_REGISTER, - LOC_CREGISTER : - begin - hr2:=right.location.register; - end; - LOC_CONSTANT : - begin - hr2:=rg.getregisterint(exprasmlist,OS_32); - cg.a_load_const_reg(exprasmlist,OS_32, - right.location.value,hr2); - end; - LOC_CREFERENCE, - LOC_REFERENCE : - begin - location_release(exprasmlist,right.location); - hr2:=rg.getregisterint(exprasmlist,OS_32); - cg.a_load_ref_reg(exprasmlist, OS_32, - right.location.reference,hr2); - end; - else - internalerror(2002032210); + LOC_REGISTER, + LOC_CREGISTER : + hr2:=right.location.register; + LOC_CONSTANT : + begin + hr2:=rg.getregisterint(exprasmlist,OS_INT); + cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2); + end; + LOC_CREFERENCE, + LOC_REFERENCE : + begin + location_release(exprasmlist,right.location); + hr2:=rg.getregisterint(exprasmlist,OS_INT); + cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,right.location.reference,hr2); + end; + else + internalerror(2002032210); end; { emit bit test operation } emit_bit_test_reg_reg(exprasmlist,hr,hr2,location.register); @@ -564,19 +559,19 @@ implementation hr2:=rg.getregisterint(exprasmlist,OS_INT); cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2); end; - LOC_REFERENCE,LOC_CREFERENCE: + LOC_REFERENCE, + LOC_CREFERENCE: begin cg.a_cmp_const_ref_label(exprasmlist,OS_8,OC_BE,31,left.location.reference,l); cg.a_jmp_always(exprasmlist,l2); cg.a_label(exprasmlist,l); location_release(exprasmlist,left.location); - hr:=rg.getregisterint(exprasmlist,OS_32); - cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,hr); + hr:=rg.getregisterint(exprasmlist,OS_INT); + cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,left.location.reference,hr); { We have to load the value into a register because btl does not accept values only refs or regs (PFV) } hr2:=rg.getregisterint(exprasmlist,OS_INT); - cg.a_load_const_reg(exprasmlist,OS_INT, - right.location.value,hr2); + cg.a_load_const_reg(exprasmlist,OS_INT,right.location.value,hr2); end; else internalerror(2002081002); @@ -598,7 +593,7 @@ implementation else { adjust for endianess differences } inc(right.location.reference.offset,(tordconstnode(left).value shr 3) xor 3); - cg.a_load_ref_reg(exprasmlist,OS_8,right.location.reference, location.register); + cg.a_load_ref_reg(exprasmlist,OS_8,location.size,right.location.reference, location.register); location_release(exprasmlist,right.location); cg.a_op_const_reg(exprasmlist,OP_SHR,location.size,tordconstnode(left).value and 7, location.register); @@ -678,16 +673,16 @@ implementation { need we to test the first value } if first and (t^._low>get_min_value(left.resulttype.def)) then begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,aword(t^._low),hregister,elselabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aword(t^._low),hregister,elselabel); end; if t^._low=t^._high then begin if t^._low-last=0 then - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement) + cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,0,hregister,t^.statement) else begin gensub(longint(t^._low-last)); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,aword(t^._low-last),scratch_reg,t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,aword(t^._low-last),scratch_reg,t^.statement); end; last:=t^._low; end @@ -708,10 +703,10 @@ implementation { present label then the lower limit can be checked } { immediately. else check the range in between: } gensub(longint(t^._low-last)); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_lt,aword(t^._low-last),scratch_reg,elselabel); + cg.a_cmp_const_reg_label(exprasmlist, opsize,jmp_lt,aword(t^._low-last),scratch_reg,elselabel); end; gensub(longint(t^._high-t^._low)); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT,jmp_le,aword(t^._high-t^._low),scratch_reg,t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, opsize,jmp_le,aword(t^._high-t^._low),scratch_reg,t^.statement); last:=t^._high; end; first:=false; @@ -728,9 +723,9 @@ implementation last:=0; first:=true; {$ifdef newra} - scratch_reg:=rg.getregisterint(exprasmlist,OS_INT); + scratch_reg:=rg.getregisterint(exprasmlist,opsize); {$else newra} - scratch_reg := cg.get_scratch_reg_int(exprasmlist,OS_INT); + scratch_reg := cg.get_scratch_reg_int(exprasmlist,opsize); {$endif} genitem(hp); {$ifdef newra} @@ -763,17 +758,17 @@ implementation begin objectlibrary.getlabel(l1); {$ifdef Delphi} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_NE, hi((t^._low)),hregister2,l1); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ, lo((t^._low)),hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_NE, hi((t^._low)),hregister2,l1); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_EQ, lo((t^._low)),hregister, t^.statement); {$else} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_NE, aword(hi(int64(t^._low))),hregister2,l1); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ, aword(lo(int64(t^._low))),hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_NE, aword(hi(int64(t^._low))),hregister2,l1); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_EQ, aword(lo(int64(t^._low))),hregister, t^.statement); {$endif} cg.a_label(exprasmlist,l1); end else begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ, aword(t^._low),hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ, aword(t^._low),hregister, t^.statement); last:=t^._low; end; end @@ -788,25 +783,25 @@ implementation begin objectlibrary.getlabel(l1); {$ifdef Delphi} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, aword(hi((t^._low))), + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_lt, aword(hi((t^._low))), hregister2, elselabel); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, aword(hi((t^._low))), + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_gt, aword(hi((t^._low))), hregister2, l1); { the comparisation of the low dword must be always unsigned! } - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_B, aword(lo((t^._low))), hregister, elselabel); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_B, aword(lo((t^._low))), hregister, elselabel); {$else} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, aword(hi(int64(t^._low))), + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_lt, aword(hi(int64(t^._low))), hregister2, elselabel); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, aword(hi(int64(t^._low))), + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_gt, aword(hi(int64(t^._low))), hregister2, l1); { the comparisation of the low dword must be always unsigned! } - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_B, aword(lo(int64(t^._low))), hregister, elselabel); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_B, aword(lo(int64(t^._low))), hregister, elselabel); {$endif} cg.a_label(exprasmlist,l1); end else begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, aword(t^._low), hregister, + cg.a_cmp_const_reg_label(exprasmlist, opsize, jmp_lt, aword(t^._low), hregister, elselabel); end; end; @@ -815,23 +810,23 @@ implementation begin objectlibrary.getlabel(l1); {$ifdef Delphi} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, aword(hi(t^._high)), hregister2, + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_lt, aword(hi(t^._high)), hregister2, t^.statement); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, aword(hi(t^._high)), hregister2, + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_gt, aword(hi(t^._high)), hregister2, l1); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_BE, aword(lo(t^._high)), hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_BE, aword(lo(t^._high)), hregister, t^.statement); {$else} - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_lt, aword(hi(int64(t^._high))), hregister2, + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_lt, aword(hi(int64(t^._high))), hregister2, t^.statement); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_gt, aword(hi(int64(t^._high))), hregister2, + cg.a_cmp_const_reg_label(exprasmlist, OS_32, jmp_gt, aword(hi(int64(t^._high))), hregister2, l1); - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_BE, aword(lo(int64(t^._high))), hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, OS_32, OC_BE, aword(lo(int64(t^._high))), hregister, t^.statement); {$endif} cg.a_label(exprasmlist,l1); end else begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, jmp_le, aword(t^._high), hregister, t^.statement); + cg.a_cmp_const_reg_label(exprasmlist, opsize, jmp_le, aword(t^._high), hregister, t^.statement); end; last:=t^._high; @@ -869,19 +864,19 @@ implementation begin if greaterlabel=lesslabel then begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_NE,p^._low,hregister, lesslabel); + cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_NE,p^._low,hregister, lesslabel); end else begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_lt,p^._low,hregister, lesslabel); - cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_gt,p^._low,hregister, greaterlabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize, jmp_lt,p^._low,hregister, lesslabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize, jmp_gt,p^._low,hregister, greaterlabel); end; cg.a_jmp_always(exprasmlist,p^.statement); end else begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,p^._low, hregister, lesslabel); - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,p^._high,hregister, greaterlabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,p^._low, hregister, lesslabel); + cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_gt,p^._high,hregister, greaterlabel); cg.a_jmp_always(exprasmlist,p^.statement); end; if assigned(p^.less) then @@ -1121,7 +1116,12 @@ begin end. { $Log$ - Revision 1.39 2003-06-01 21:38:06 peter + Revision 1.40 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.39 2003/06/01 21:38:06 peter * getregisterfpu size parameter added * op_const_reg size parameter added * sparc updates diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 5cf59b982a..5b4c055cfe 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -64,7 +64,7 @@ interface const locpara : tparalocation); procedure genentrycode(list:TAAsmoutput;inlined:boolean); - procedure gen_stackalloc_code(list:Taasmoutput;stackframe:cardinal); + procedure gen_stackalloc_code(list:Taasmoutput;stackframe:longint); procedure genexitcode(list:Taasmoutput;inlined:boolean); procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint); @@ -430,7 +430,7 @@ implementation rg.isaddressregister(hregister)} then hregister:=rg.getregisterint(list,dst_size); end; - hregister.number:=(hregister.number and not $ff) or cgsize2subreg(dst_size); + hregister:=rg.makeregsize(hregister,dst_size); {$ifdef newra} rg.add_constraints(hregister.number); {$endif} @@ -456,7 +456,7 @@ implementation if (TCGSize2Size[dst_size]R_INTREGISTER then - internalerror(200302024); - hreg:=p.location.register; - p.location.register.number:=(p.location.register.number and not $ff) or cgsize2subreg(cgsize); - end; inc(pushedparasize,alignment); if calloption=pocall_inline then begin @@ -981,13 +959,10 @@ implementation cg.g_concatcopy(list,p.location.reference,href,size,false,false) end else - cg.a_load_loc_ref(list,p.location,href); + cg.a_load_loc_ref(list,p.location.size,p.location,href); end else cg.a_param_loc(list,p.location,locpara); - { restore old register } - if p.location.loc in [LOC_REGISTER,LOC_CREGISTER] then - p.location.register:=hreg; end; location_release(list,p.location); end; @@ -1143,7 +1118,7 @@ implementation {$else} tmpreg:=cg.get_scratch_reg_address(list); {$endif} - cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg); + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,tmpreg); reference_reset_base(href,tmpreg,0); cg.g_initialize(list,tvarsym(p).vartype.def,href,false); {$ifdef newra} @@ -1239,7 +1214,6 @@ implementation procedure initretvalue(list:taasmoutput); var - paraloc : tparalocation; href : treference; begin if not is_void(current_procdef.rettype.def) then @@ -1257,7 +1231,7 @@ implementation cg.g_initialize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption)); { load the pointer to the initialized retvalue in te register } if (tvarsym(current_procdef.funcretsym).reg.enum <> R_NO) then - cg.a_load_ref_reg(list,OS_ADDR,href,tvarsym(current_procdef.funcretsym).reg); + cg.a_load_ref_reg(list,OS_ADDR,def_cgsize(current_procdef.rettype.def),href,tvarsym(current_procdef.funcretsym).reg); end; end; end; @@ -1283,7 +1257,7 @@ implementation location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def)); resloc.register := ressym.reg; end - else + else begin location_reset(resloc,LOC_REFERENCE,def_cgsize(current_procdef.rettype.def)); reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address); @@ -1312,7 +1286,8 @@ implementation {$endif cpu64bit} begin hreg.enum:=R_INTREGISTER; - hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(resloc.size); + hreg.number:=NR_FUNCTION_RETURN_REG; + hreg:=rg.makeregsize(hreg,resloc.size); cg.a_load_loc_reg(list,resloc.size,resloc,hreg); end; end; @@ -1400,7 +1375,7 @@ implementation LOC_CREFERENCE: begin reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address); - cg.a_load_ref_reg(list,hp.paraloc.size,href,tvarsym(hp.parasym).reg); + cg.a_load_ref_reg(list,hp.paraloc.size,hp.paraloc.size,href,tvarsym(hp.parasym).reg); end; else internalerror(2003053010); @@ -1414,7 +1389,7 @@ implementation LOC_CREGISTER, LOC_REGISTER: if not(hp.paraloc.size in [OS_S64,OS_64]) then - cg.a_load_reg_ref(list,hp.paraloc.size,hp.paraloc.register,href) + cg.a_load_reg_ref(list,hp.paraloc.size,hp.paraloc.size,hp.paraloc.register,href) else cg64.a_load64_reg_ref(list,hp.paraloc.register64,href); LOC_FPUREGISTER, @@ -1448,7 +1423,7 @@ implementation tg.GetTemp(list,POINTER_SIZE,tt_noreuse,current_procinfo.save_stackptr_ref); rsp.enum:=R_INTREGISTER; rsp.number:=NR_STACK_POINTER_REG; - cg.a_load_reg_ref(list,OS_ADDR,rsp,current_procinfo.save_stackptr_ref); + cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,rsp,current_procinfo.save_stackptr_ref); end; { the actual profile code can clobber some registers, @@ -1533,7 +1508,7 @@ implementation end; - procedure gen_stackalloc_code(list:Taasmoutput;stackframe:cardinal); + procedure gen_stackalloc_code(list:Taasmoutput;stackframe:longint); var hs:string; @@ -1617,14 +1592,10 @@ implementation srsym : tsym; usesacc, usesacchi, - usesself,usesfpu : boolean; - pd : tprocdef; - rsp,tmpreg,r : Tregister; - retsize:cardinal; - nostackframe:boolean; + usesfpu : boolean; + rsp,r : Tregister; + retsize : longint; begin -{ nostackframe:=current_procinfo.framepointer.number=NR_STACK_POINTER_REG;} - if aktexitlabel.is_used then cg.a_label(list,aktexitlabel); @@ -1685,7 +1656,7 @@ implementation if not assigned(srsym) then internalerror(200305058); reference_reset_base(href,current_procinfo.framepointer,tvarsym(srsym).adjusted_address); - cg.a_load_ref_reg(list,OS_ADDR,href,r); + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,r); cg.a_reg_dealloc(list,r); usesacc:=true; end @@ -1709,7 +1680,7 @@ implementation begin rsp.enum:=R_INTREGISTER; rsp.number:=NR_STACK_POINTER_REG; - cg.a_load_ref_reg(list,OS_ADDR,current_procinfo.save_stackptr_ref,rsp); + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_stackptr_ref,rsp); tg.UngetTemp(list,current_procinfo.save_stackptr_ref); end; @@ -1850,7 +1821,7 @@ implementation location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def)); resloc.register := ressym.reg; end - else + else begin location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def)); reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address); @@ -1971,7 +1942,12 @@ implementation end. { $Log$ - Revision 1.120 2003-06-03 15:49:49 jonas + Revision 1.121 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.120 2003/06/03 15:49:49 jonas * fixed ref/loc problems Revision 1.119 2003/06/03 15:06:37 daniel diff --git a/compiler/regvars.pas b/compiler/regvars.pas index b2ceab9c70..4026588add 100644 --- a/compiler/regvars.pas +++ b/compiler/regvars.pas @@ -307,6 +307,7 @@ implementation procedure store_regvar(asml: TAAsmoutput; reg: tregister); var i: longint; + cgsize : tcgsize; r : tregister; hr: treference; regvarinfo: pregvarinfo; @@ -330,7 +331,8 @@ implementation if not(vsym.varspez in [vs_const,vs_var,vs_out]) then begin reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address); - cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr); + cgsize:=def_cgsize(vsym.vartype.def); + cg.a_load_reg_ref(asml,cgsize,cgsize,vsym.reg,hr); end; asml.concat(tai_regalloc.dealloc(vsym.reg)); exclude(rg.regvar_loaded_int,reg.number shr 8); @@ -354,7 +356,8 @@ implementation if not(vsym.varspez in [vs_const,vs_var,vs_out]) then begin reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address); - cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr); + cgsize:=def_cgsize(vsym.vartype.def); + cg.a_load_reg_ref(asml,cgsize,cgsize,vsym.reg,hr); end; asml.concat(tai_regalloc.dealloc(vsym.reg)); rg.regvar_loaded_other[r.enum] := false; @@ -389,7 +392,7 @@ implementation opsize := OS_ADDR else opsize := def_cgsize(vsym.vartype.def); - cg.a_load_ref_reg(asml,opsize,hr,reg); + cg.a_load_ref_reg(asml,opsize,opsize,hr,reg); include(rg.regvar_loaded_int,reg.number shr 8); end; end @@ -406,7 +409,7 @@ implementation opsize := OS_ADDR else opsize := def_cgsize(vsym.vartype.def); - cg.a_load_ref_reg(asml,opsize,hr,reg); + cg.a_load_ref_reg(asml,opsize,opsize,hr,reg); rg.regvar_loaded_other[r.enum] := true; end; end; @@ -608,7 +611,12 @@ end. { $Log$ - Revision 1.54 2003-06-03 13:01:59 daniel + Revision 1.55 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.54 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.53 2003/05/31 20:33:57 jonas diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas index e7b2cb7970..43921dc9d6 100644 --- a/compiler/rgobj.pas +++ b/compiler/rgobj.pas @@ -464,7 +464,7 @@ unit rgobj; procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize); procedure location_release(list: taasmoutput; const l : tlocation); procedure location_freetemp(list: taasmoutput; const l : tlocation); - procedure location_copy(var destloc,sourceloc : tlocation); + procedure location_copy(var destloc:tlocation; const sourceloc : tlocation); procedure location_swap(var destloc,sourceloc : tlocation); type @@ -990,7 +990,7 @@ unit rgobj; saved[r].ofs:=hr.offset; r2.enum:=R_INTREGISTER; r2.number:=r shl 8 or R_SUBWHOLE; - cg.a_load_reg_ref(list,OS_INT,r2,hr); + cg.a_load_reg_ref(list,OS_INT,OS_INT,r2,hr); cg.a_reg_dealloc(list,r2); include(unusedregsint,r); inc(countunusedregsint); @@ -1080,7 +1080,7 @@ unit rgobj; r2.enum:=R_INTREGISTER; r2.number:=r shl 8 or R_SUBWHOLE; cg.a_reg_alloc(list,r2); - cg.a_load_ref_reg(list,OS_INT,hr,r2); + cg.a_load_ref_reg(list,OS_INT,OS_INT,hr,r2); if not (r in unusedregsint) then { internalerror(10) in n386cal we always save/restore the reg *state* @@ -2050,7 +2050,7 @@ unit rgobj; {Remove node u from the interference graph and remove all collected move instructions it is associated with.} - var i:byte; + var i:byte; j,k,count:cardinal; v:Tsuperregister; m,n:Tmoveins; @@ -2439,7 +2439,7 @@ unit rgobj; end; - procedure location_copy(var destloc,sourceloc : tlocation); + procedure location_copy(var destloc:tlocation; const sourceloc : tlocation); begin destloc:=sourceloc; end; @@ -2463,7 +2463,12 @@ end. { $Log$ - Revision 1.49 2003-06-03 13:01:59 daniel + Revision 1.50 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.49 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.48 2003/06/01 21:38:06 peter diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index fd86b2fd6b..285e308dd7 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -34,7 +34,7 @@ unit cgx86; cginfo,cgbase,cgobj, aasmbase,aasmtai,aasmcpu, cpubase,cpuinfo, - node,symconst; + symconst,symtype; type tcgx86 = class(tcg) @@ -67,11 +67,11 @@ unit cgx86; size: tcgsize; src1, src2, dst: tregister); override; { move instructions } - procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);override; - procedure a_load_const_ref(list : taasmoutput; size: tcgsize; a : aword;const ref : treference);override; - procedure a_load_reg_ref(list : taasmoutput; size: tcgsize; reg : tregister;const ref : treference);override; - procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;reg : tregister);override; - procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override; + procedure a_load_const_reg(list : taasmoutput; tosize: tcgsize; a : aword;reg : tregister);override; + procedure a_load_const_ref(list : taasmoutput; tosize: tcgsize; a : aword;const ref : treference);override; + procedure a_load_reg_ref(list : taasmoutput;fromsize,tosize: tcgsize; reg : tregister;const ref : treference);override; + procedure a_load_ref_reg(list : taasmoutput;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override; + procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize: tcgsize;reg1,reg2 : tregister);override; procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);override; { fpu move instructions } @@ -121,11 +121,13 @@ unit cgx86; procedure g_save_all_registers(list : taasmoutput);override; procedure g_restore_all_registers(list : taasmoutput;accused,acchiused:boolean);override; - procedure g_overflowcheck(list: taasmoutput; const p: tnode);override; + procedure g_overflowcheck(list: taasmoutput; const l:tlocation;def:tdef);override; - private + protected procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel); - procedure sizes2load(s1 : tcgsize;s2 : topsize; var op: tasmop; var s3: topsize); + procedure check_register_size(size:tcgsize;reg:tregister); + private + procedure sizes2load(s1,s2 : tcgsize;var op: tasmop; var s3: topsize); procedure floatload(list: taasmoutput; t : tcgsize;const ref : treference); procedure floatstore(list: taasmoutput; t : tcgsize;const ref : treference); @@ -164,23 +166,24 @@ unit cgx86; This is private property, keep out! :) ****************************************************************************} - procedure tcgx86.sizes2load(s1 : tcgsize;s2: topsize; var op: tasmop; var s3: topsize); + procedure tcgx86.sizes2load(s1,s2 : tcgsize; var op: tasmop; var s3: topsize); begin case s2 of - S_B: + OS_8,OS_S8 : if S1 in [OS_8,OS_S8] then s3 := S_B else internalerror(200109221); - S_W: + OS_16,OS_S16: case s1 of OS_8,OS_S8: s3 := S_BW; OS_16,OS_S16: s3 := S_W; - else internalerror(200109222); + else + internalerror(200109222); end; - S_L: + OS_32,OS_S32: case s1 of OS_8,OS_S8: s3 := S_BL; @@ -188,11 +191,11 @@ unit cgx86; s3 := S_WL; OS_32,OS_S32: s3 := S_L; - else internalerror(200109223); + else + internalerror(200109223); end; {$ifdef x86_64} - S_D, - S_Q: + OS_64,OS_S64: case s1 of OS_8,OS_S8: s3 := S_BQ; @@ -202,10 +205,12 @@ unit cgx86; s3 := S_LQ; OS_64,OS_S64: s3 := S_Q; - else internalerror(200304302); + else + internalerror(200304302); end; {$endif x86_64} - else internalerror(200109227); + else + internalerror(200109227); end; if s3 in [S_B,S_W,S_L,S_Q] then op := A_MOV @@ -303,6 +308,15 @@ unit cgx86; end; + procedure tcgx86.check_register_size(size:tcgsize;reg:tregister); + begin + if (reg.enum<>R_INTREGISTER) then + internalerror(200301081); + if TCGSize2OpSize[size]<>TCGSize2OpSize[reg_cgsize(reg)] then + internalerror(200306031); + end; + + {**************************************************************************** Assembler code ****************************************************************************} @@ -331,6 +345,7 @@ unit cgx86; procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation); begin + check_register_size(size,r); case size of OS_8,OS_S8, OS_16,OS_S16: @@ -375,26 +390,25 @@ unit cgx86; procedure tcgx86.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation); var - tmpreg: tregister; + pushsize : tcgsize; + tmpreg : tregister; begin case size of OS_8,OS_S8, OS_16,OS_S16: begin + if target_info.alignment.paraalign = 2 then + pushsize:=OS_16 + else + pushsize:=OS_32; {$ifdef newra} - if target_info.alignment.paraalign = 2 then - tmpreg:=rg.getregisterint(list,OS_16) - else - tmpreg:=rg.getregisterint(list,OS_32); + tmpreg:=rg.getregisterint(list,pushsize) {$else} - if target_info.alignment.paraalign = 2 then - tmpreg:=get_scratch_reg_int(list,OS_16) - else - tmpreg:=get_scratch_reg_int(list,OS_32); + tmpreg:=get_scratch_reg_int(list,pushsize); {$endif} - a_load_ref_reg(list,size,r,tmpreg); - list.concat(taicpu.op_reg(A_PUSH,S_L,tmpreg)); + a_load_ref_reg(list,size,pushsize,r,tmpreg); + list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg)); {$ifdef newra} rg.ungetregisterint(list,tmpreg); {$else} @@ -474,41 +488,41 @@ unit cgx86; {********************** load instructions ********************} - procedure tcgx86.a_load_const_reg(list : taasmoutput; size: TCGSize; a : aword; reg : TRegister); + procedure tcgx86.a_load_const_reg(list : taasmoutput; tosize: TCGSize; a : aword; reg : TRegister); begin + check_register_size(tosize,reg); { the optimizer will change it to "xor reg,reg" when loading zero, } { no need to do it here too (JM) } - list.concat(taicpu.op_const_reg(A_MOV,TCGSize2OpSize[size],a,reg)) + list.concat(taicpu.op_const_reg(A_MOV,TCGSize2OpSize[tosize],a,reg)) end; - procedure tcgx86.a_load_const_ref(list : taasmoutput; size: tcgsize; a : aword;const ref : treference); + procedure tcgx86.a_load_const_ref(list : taasmoutput; tosize: tcgsize; a : aword;const ref : treference); begin - list.concat(taicpu.op_const_ref(A_MOV,TCGSize2OpSize[size],a,ref)); + list.concat(taicpu.op_const_ref(A_MOV,TCGSize2OpSize[tosize],a,ref)); end; - procedure tcgx86.a_load_reg_ref(list : taasmoutput; size: TCGSize; reg : tregister;const ref : treference); - - begin - list.concat(taicpu.op_reg_ref(A_MOV,TCGSize2OpSize[size],reg, - ref)); - end; - - - procedure tcgx86.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref: treference;reg : tregister); - + procedure tcgx86.a_load_reg_ref(list : taasmoutput; fromsize,tosize: TCGSize; reg : tregister;const ref : treference); var op: tasmop; - o,s: topsize; - + s: topsize; begin - if reg.enum<>R_INTREGISTER then - internalerror(200302058); - o:=reg2opsize(reg); - sizes2load(size,o,op,s); + check_register_size(fromsize,reg); + sizes2load(fromsize,tosize,op,s); + list.concat(taicpu.op_reg_ref(op,s,reg,ref)); + end; + + + procedure tcgx86.a_load_ref_reg(list : taasmoutput;fromsize,tosize : tcgsize;const ref: treference;reg : tregister); + var + op: tasmop; + s: topsize; + begin + check_register_size(tosize,reg); + sizes2load(fromsize,tosize,op,s); list.concat(taicpu.op_ref_reg(op,s,ref,reg)); end; @@ -522,13 +536,10 @@ unit cgx86; instr:Taicpu; begin - if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then - begin - sizes2load(fromsize,reg2opsize(reg2),op,s); - eq:=(reg1.number shr 8)=(reg2.number shr 8); - end - else - internalerror(200301081); + check_register_size(fromsize,reg1); + check_register_size(tosize,reg2); + sizes2load(fromsize,tosize,op,s); + eq:=(reg1.number shr 8)=(reg2.number shr 8); if eq then begin { "mov reg1, reg1" doesn't make sense } @@ -651,8 +662,7 @@ unit cgx86; power: longint; begin - if reg.enum<>R_INTREGISTER then - internalerror(200302034); + check_register_size(size,reg); case op of OP_DIV, OP_IDIV: begin @@ -822,18 +832,15 @@ unit cgx86; instr:Taicpu; begin - if src.enum<>R_INTREGISTER then - internalerror(200302025); - if dst.enum<>R_INTREGISTER then - internalerror(200302025); + check_register_size(size,src); + check_register_size(size,dst); r.enum:=R_INTREGISTER; dstsize := tcgsize2opsize[size]; - dst.number:=(dst.number and not $ff) or cgsize2subreg(size); case op of OP_NEG,OP_NOT: begin - if src.number <> NR_NO then - internalerror(200112291); + if src.number<>dst.number then + a_load_reg_reg(list,size,size,src,dst); list.concat(taicpu.op_reg(TOpCG2AsmOp[op],dstsize,dst)); end; OP_MUL,OP_DIV,OP_IDIV: @@ -917,68 +924,62 @@ unit cgx86; end; - procedure tcgx86.a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); - begin - case op of - OP_NEG,OP_NOT,OP_IMUL: - begin - inherited a_op_ref_reg(list,op,size,ref,reg); - end; - OP_MUL,OP_DIV,OP_IDIV: - { special stuff, needs separate handling inside code } - { generator } - internalerror(200109239); - else - begin - reg := rg.makeregsize(reg,size); - list.concat(taicpu.op_ref_reg(TOpCG2AsmOp[op],tcgsize2opsize[size],ref,reg)); - end; - end; - end; + procedure tcgx86.a_op_ref_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); + begin + check_register_size(size,reg); + case op of + OP_NEG,OP_NOT,OP_IMUL: + begin + inherited a_op_ref_reg(list,op,size,ref,reg); + end; + OP_MUL,OP_DIV,OP_IDIV: + { special stuff, needs separate handling inside code } + { generator } + internalerror(200109239); + else + begin + reg := rg.makeregsize(reg,size); + list.concat(taicpu.op_ref_reg(TOpCG2AsmOp[op],tcgsize2opsize[size],ref,reg)); + end; + end; + end; - procedure tcgx86.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); - begin - if reg.enum<>R_INTREGISTER then - internalerror(200302036); - case op of - OP_NEG,OP_NOT: - begin - if reg.number<>NR_NO then - internalerror(200109237); - list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],ref)); - end; - OP_IMUL: - begin - { this one needs a load/imul/store, which is the default } - inherited a_op_ref_reg(list,op,size,ref,reg); - end; - OP_MUL,OP_DIV,OP_IDIV: - { special stuff, needs separate handling inside code } - { generator } - internalerror(200109238); - else - begin - list.concat(taicpu.op_reg_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],reg,ref)); - end; - end; - end; + procedure tcgx86.a_op_reg_ref(list : taasmoutput; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); + begin + check_register_size(size,reg); + case op of + OP_NEG,OP_NOT: + begin + if reg.number<>NR_NO then + internalerror(200109237); + list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],ref)); + end; + OP_IMUL: + begin + { this one needs a load/imul/store, which is the default } + inherited a_op_ref_reg(list,op,size,ref,reg); + end; + OP_MUL,OP_DIV,OP_IDIV: + { special stuff, needs separate handling inside code } + { generator } + internalerror(200109238); + else + begin + list.concat(taicpu.op_reg_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],reg,ref)); + end; + end; + end; - procedure tcgx86.a_op_const_reg_reg(list: taasmoutput; op: TOpCg; - size: tcgsize; a: aword; src, dst: tregister); + procedure tcgx86.a_op_const_reg_reg(list: taasmoutput; op: TOpCg; size: tcgsize; a: aword; src, dst: tregister); var tmpref: treference; power: longint; - opsize: topsize; begin - if src.enum<>R_INTREGISTER then - internalerror(200302057); - if dst.enum<>R_INTREGISTER then - internalerror(200302057); - opsize := reg2opsize(src); - if (opsize <> S_L) or - not (size in [OS_32,OS_S32]) then + check_register_size(size,src); + check_register_size(size,dst); + if not (size in [OS_32,OS_S32]) then begin inherited a_op_const_reg_reg(list,op,size,a,src,dst); exit; @@ -1016,22 +1017,15 @@ unit cgx86; end; end; - procedure tcgx86.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg; - size: tcgsize; src1, src2, dst: tregister); + + procedure tcgx86.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg;size: tcgsize; src1, src2, dst: tregister); var tmpref: treference; - opsize: topsize; begin - if src1.enum>lastreg then - internalerror(200201081); - if src2.enum>lastreg then - internalerror(200201081); - if dst.enum>lastreg then - internalerror(200201081); - opsize := reg2opsize(src1); - if (opsize <> S_L) or - (reg2opsize(src2) <> S_L) or - not (size in [OS_32,OS_S32]) then + check_register_size(size,src1); + check_register_size(size,src2); + check_register_size(size,dst); + if not(size in [OS_32,OS_S32]) then begin inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst); exit; @@ -1058,72 +1052,65 @@ unit cgx86; {*************** compare instructructions ****************} - procedure tcgx86.a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister; - l : tasmlabel); + procedure tcgx86.a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister; + l : tasmlabel); - begin - if reg.enum=R_INTREGISTER then - begin - if (a = 0) then - list.concat(taicpu.op_reg_reg(A_TEST,tcgsize2opsize[size],reg,reg)) - else - list.concat(taicpu.op_const_reg(A_CMP,tcgsize2opsize[size],a,reg)); - end - else - internalerror(200303131); - a_jmp_cond(list,cmp_op,l); - end; + begin + if reg.enum=R_INTREGISTER then + begin + if (a = 0) then + list.concat(taicpu.op_reg_reg(A_TEST,tcgsize2opsize[size],reg,reg)) + else + list.concat(taicpu.op_const_reg(A_CMP,tcgsize2opsize[size],a,reg)); + end + else + internalerror(200303131); + a_jmp_cond(list,cmp_op,l); + end; - procedure tcgx86.a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference; - l : tasmlabel); + procedure tcgx86.a_cmp_const_ref_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;const ref : treference; + l : tasmlabel); - begin - list.concat(taicpu.op_const_ref(A_CMP,TCgSize2OpSize[size],a,ref)); - a_jmp_cond(list,cmp_op,l); - end; - - procedure tcgx86.a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp; - reg1,reg2 : tregister;l : tasmlabel); - - begin - if reg1.enum<>R_INTREGISTER then - internalerror(200101081); - if reg2.enum<>R_INTREGISTER then - internalerror(200101081); - if reg2opsize(reg1) <> reg2opsize(reg2) then - internalerror(200109226); - list.concat(taicpu.op_reg_reg(A_CMP,reg2opsize(reg1),reg1,reg2)); - a_jmp_cond(list,cmp_op,l); - end; + begin + list.concat(taicpu.op_const_ref(A_CMP,TCgSize2OpSize[size],a,ref)); + a_jmp_cond(list,cmp_op,l); + end; - procedure tcgx86.a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister;l : tasmlabel); - begin - if reg.enum<>R_INTREGISTER then - internalerror(200302059); - reg.number:=(reg.number and not $ff) or cgsize2subreg(size); - list.concat(taicpu.op_ref_reg(A_CMP,tcgsize2opsize[size],ref,reg)); - a_jmp_cond(list,cmp_op,l); - end; + procedure tcgx86.a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp; + reg1,reg2 : tregister;l : tasmlabel); + + begin + check_register_size(size,reg1); + check_register_size(size,reg2); + list.concat(taicpu.op_reg_reg(A_CMP,TCgSize2OpSize[size],reg1,reg2)); + a_jmp_cond(list,cmp_op,l); + end; - procedure tcgx86.a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel); + procedure tcgx86.a_cmp_ref_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister;l : tasmlabel); + begin + check_register_size(size,reg); + list.concat(taicpu.op_ref_reg(A_CMP,TCgSize2OpSize[size],ref,reg)); + a_jmp_cond(list,cmp_op,l); + end; - var - ai : taicpu; - begin - if cond=OC_None then - ai := Taicpu.Op_sym(A_JMP,S_NO,l) - else - begin - ai:=Taicpu.Op_sym(A_Jcc,S_NO,l); - ai.SetCondition(TOpCmp2AsmCond[cond]); - end; - ai.is_jmp:=true; - list.concat(ai); - end; + procedure tcgx86.a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel); + var + ai : taicpu; + begin + if cond=OC_None then + ai := Taicpu.Op_sym(A_JMP,S_NO,l) + else + begin + ai:=Taicpu.Op_sym(A_Jcc,S_NO,l); + ai.SetCondition(TOpCmp2AsmCond[cond]); + end; + ai.is_jmp:=true; + list.concat(ai); + end; procedure tcgx86.a_jmp_flags(list : taasmoutput;const f : TResFlags;l: tasmlabel); @@ -1137,26 +1124,21 @@ unit cgx86; end; - procedure tcgx86.g_flags2reg(list: taasmoutput; size: TCgSize; const f: tresflags; reg: TRegister); - - var - ai : taicpu; - hreg : tregister; - begin - if reg.enum<>R_INTREGISTER then - internalerror(200202031); - hreg.enum:=R_INTREGISTER; - hreg.number:=(reg.number and not $ff) or R_SUBL; - ai:=Taicpu.op_reg(A_SETcc,S_B,hreg); - ai.setcondition(flags_to_cond(f)); - list.concat(ai); - if (reg.number <> hreg.number) then - a_load_reg_reg(list,OS_8,size,hreg,reg); - end; + procedure tcgx86.g_flags2reg(list: taasmoutput; size: TCgSize; const f: tresflags; reg: TRegister); + var + ai : taicpu; + hreg : tregister; + begin + hreg:=rg.makeregsize(reg,OS_8); + ai:=Taicpu.op_reg(A_SETcc,S_B,hreg); + ai.setcondition(flags_to_cond(f)); + list.concat(ai); + if (reg.number <> hreg.number) then + a_load_reg_reg(list,OS_8,size,hreg,reg); + end; procedure tcgx86.g_flags2ref(list: taasmoutput; size: TCgSize; const f: tresflags; const ref: TReference); - var ai : taicpu; begin @@ -1311,10 +1293,10 @@ unit cgx86; for i:=1 to helpsize do begin r:=rg.getexplicitregisterint(list,NR_EDI); - a_load_ref_reg(list,OS_32,srcref,r); + a_load_ref_reg(list,OS_32,OS_32,srcref,r); If (len = 4) and delsource then reference_release(list,source); - a_load_reg_ref(list,OS_32,r,dstref); + a_load_reg_ref(list,OS_32,OS_32,r,dstref); inc(srcref.offset,4); inc(dstref.offset,4); dec(len,4); @@ -1323,10 +1305,10 @@ unit cgx86; if len>1 then begin r:=rg.getexplicitregisterint(list,NR_DI); - a_load_ref_reg(list,OS_16,srcref,r); + a_load_ref_reg(list,OS_16,OS_16,srcref,r); If (len = 2) and delsource then reference_release(list,source); - a_load_reg_ref(list,OS_16,r,dstref); + a_load_reg_ref(list,OS_16,OS_16,r,dstref); inc(srcref.offset,2); inc(dstref.offset,2); dec(len,2); @@ -1370,10 +1352,10 @@ unit cgx86; r:=rg.getexplicitregisterint(list,NR_EDI); a_load_reg_reg(list,OS_32,OS_32,reg32,r); end; - a_load_ref_reg(list,OS_8,srcref,reg8); + a_load_ref_reg(list,OS_8,OS_8,srcref,reg8); If delsource and (len=1) then reference_release(list,source); - a_load_reg_ref(list,OS_8,reg8,dstref); + a_load_reg_ref(list,OS_8,OS_8,reg8,dstref); if swap then begin r.number:=NR_EDI; @@ -1391,7 +1373,7 @@ unit cgx86; if loadref then begin srcreg:=maybepush(NR_ESI,esipushed); - a_load_ref_reg(list,OS_ADDR,source,srcreg) + a_load_ref_reg(list,OS_ADDR,OS_ADDR,source,srcreg) end else begin @@ -1585,11 +1567,11 @@ unit cgx86; { load count } r2.number:=NR_ECX; - a_load_ref_reg(list,OS_INT,lenref,r2); + a_load_ref_reg(list,OS_INT,OS_INT,lenref,r2); { load source } r2.number:=NR_ESI; - a_load_ref_reg(list,OS_INT,ref,r2); + a_load_ref_reg(list,OS_INT,OS_INT,ref,r2); { scheduled .... } r2.number:=NR_ECX; @@ -1627,7 +1609,7 @@ unit cgx86; list.concat(Taicpu.op_reg(A_POP,S_L,r2)); { patch the new address } - a_load_reg_ref(list,OS_INT,rsp,ref); + a_load_reg_ref(list,OS_INT,OS_INT,rsp,ref); end; @@ -1924,7 +1906,7 @@ unit cgx86; { produces if necessary overflowcode } - procedure tcgx86.g_overflowcheck(list: taasmoutput; const p: tnode); + procedure tcgx86.g_overflowcheck(list: taasmoutput; const l:tlocation;def:tdef); var hl : tasmlabel; ai : taicpu; @@ -1933,10 +1915,10 @@ unit cgx86; if not(cs_check_overflow in aktlocalswitches) then exit; objectlibrary.getlabel(hl); - if not ((p.resulttype.def.deftype=pointerdef) or - ((p.resulttype.def.deftype=orddef) and - (torddef(p.resulttype.def).typ in [u64bit,u16bit,u32bit,u8bit,uchar, - bool8bit,bool16bit,bool32bit]))) then + if not ((def.deftype=pointerdef) or + ((def.deftype=orddef) and + (torddef(def).typ in [u64bit,u16bit,u32bit,u8bit,uchar, + bool8bit,bool16bit,bool32bit]))) then cond:=C_NO else cond:=C_NB; @@ -1953,7 +1935,12 @@ unit cgx86; end. { $Log$ - Revision 1.50 2003-06-03 13:01:59 daniel + Revision 1.51 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.50 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.49 2003/06/01 21:38:07 peter diff --git a/compiler/x86/cpubase.pas b/compiler/x86/cpubase.pas index b4a7511868..5c618d8f89 100644 --- a/compiler/x86/cpubase.pas +++ b/compiler/x86/cpubase.pas @@ -543,6 +543,7 @@ uses function cgsize2subreg(s:Tcgsize):Tsubregister; function reg2opsize(r:tregister):topsize; function is_calljmp(o:tasmop):boolean; + procedure inverse_flags(var f: TResFlags); function flags_to_cond(const f: TResFlags) : TAsmCond; @@ -704,6 +705,15 @@ implementation end; + procedure inverse_flags(var f: TResFlags); + const + inv_flags: array[TResFlags] of TResFlags = + (F_NE,F_E,F_LE,F_GE,F_L,F_G,F_NC,F_C,F_BE,F_B,F_AE,F_A); + begin + f:=inv_flags[f]; + end; + + function flags_to_cond(const f: TResFlags) : TAsmCond; const flags_2_cond : array[TResFlags] of TAsmCond = @@ -716,7 +726,12 @@ implementation end. { $Log$ - Revision 1.6 2003-06-03 13:01:59 daniel + Revision 1.7 2003-06-03 21:11:09 peter + * cg.a_load_* get a from and to size specifier + * makeregsize only accepts newregister + * i386 uses generic tcgnotnode,tcgunaryminus + + Revision 1.6 2003/06/03 13:01:59 daniel * Register allocator finished Revision 1.5 2003/05/30 23:57:08 peter