From 24e2741659a57524f683389b5dccdcc0b0519383 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Wed, 12 Mar 2003 22:43:38 +0000 Subject: [PATCH] * more powerpc and generic fixes related to the new register allocator --- compiler/ncgmem.pas | 9 ++- compiler/powerpc/aasmcpu.pas | 63 ++++++++++++++++- compiler/powerpc/agppcgas.pas | 22 ++++-- compiler/powerpc/cgcpu.pas | 126 +++++++++++++++++----------------- compiler/psub.pas | 7 +- 5 files changed, 152 insertions(+), 75 deletions(-) diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 8ef340a2cd..3fbf209db6 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -522,12 +522,12 @@ implementation procedure tcgvecnode.update_reference_reg_mul(reg:tregister;l:aword); begin - if location.reference.base.enum=R_NO then + if location.reference.base.number=NR_NO then begin cg.a_op_const_reg(exprasmlist,OP_IMUL,l,reg); location.reference.base:=reg; end - else if location.reference.index.enum=R_NO then + else if location.reference.index.number=NR_NO then begin cg.a_op_const_reg(exprasmlist,OP_IMUL,l,reg); location.reference.index:=reg; @@ -925,7 +925,10 @@ begin end. { $Log$ - Revision 1.42 2003-02-19 22:00:14 daniel + Revision 1.43 2003-03-12 22:43:38 jonas + * more powerpc and generic fixes related to the new register allocator + + Revision 1.42 2003/02/19 22:00:14 daniel * Code generator converted to new register notation - Horribily outdated todo.txt removed diff --git a/compiler/powerpc/aasmcpu.pas b/compiler/powerpc/aasmcpu.pas index fb7e03dbf5..9f27bdf66c 100644 --- a/compiler/powerpc/aasmcpu.pas +++ b/compiler/powerpc/aasmcpu.pas @@ -109,6 +109,8 @@ implementation constructor taicpu.op_reg(op : tasmop;_op1 : tregister); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031207); ops:=1; loadreg(0,_op1); end; @@ -125,6 +127,10 @@ implementation constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031205); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031206); ops:=2; loadreg(0,_op1); loadreg(1,_op2); @@ -133,6 +139,8 @@ implementation constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: longint); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031208); ops:=2; loadreg(0,_op1); loadconst(1,aword(_op2)); @@ -141,6 +149,8 @@ implementation constructor taicpu.op_const_reg(op:tasmop; _op1: longint; _op2: tregister); begin inherited create(op); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031209); ops:=2; loadconst(0,aword(_op1)); loadreg(1,_op2); @@ -150,6 +160,8 @@ implementation constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031210); ops:=2; loadreg(0,_op1); loadref(1,_op2); @@ -168,6 +180,12 @@ implementation constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031211); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031212); + if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then + internalerror(2003031213); ops:=3; loadreg(0,_op1); loadreg(1,_op2); @@ -177,6 +195,10 @@ implementation constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031214); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031215); ops:=3; loadreg(0,_op1); loadreg(1,_op2); @@ -186,6 +208,10 @@ implementation constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031216); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031217); ops:=3; loadreg(0,_op1); loadreg(1,_op2); @@ -195,6 +221,10 @@ implementation constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031218); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031219); ops:=3; loadreg(0,_op1); loadreg(1,_op2); @@ -204,6 +234,10 @@ implementation constructor taicpu.op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister); begin inherited create(op); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031221); + if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then + internalerror(2003031220); ops:=3; loadconst(0,aword(_op1)); loadreg(1,_op2); @@ -213,6 +247,8 @@ implementation constructor taicpu.op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint); begin inherited create(op); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031222); ops:=3; loadconst(0,aword(_op1)); loadreg(1,_op2); @@ -223,6 +259,14 @@ implementation constructor taicpu.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031223); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031224); + if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then + internalerror(2003031225); + if (_op4.enum = R_INTREGISTER) and (_op4.number = NR_NO) then + internalerror(2003031226); ops:=4; loadreg(0,_op1); loadreg(1,_op2); @@ -233,6 +277,12 @@ implementation constructor taicpu.op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031227); + if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then + internalerror(2003031228); + if (_op4.enum = R_INTREGISTER) and (_op4.number = NR_NO) then + internalerror(2003031229); ops:=4; loadreg(0,_op1); loadbool(1,_op2); @@ -243,6 +293,10 @@ implementation constructor taicpu.op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031230); + if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then + internalerror(2003031231); ops:=4; loadreg(0,_op1); loadbool(0,_op2); @@ -253,6 +307,10 @@ implementation constructor taicpu.op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint); begin inherited create(op); + if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then + internalerror(2003031232); + if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then + internalerror(2003031233); ops:=5; loadreg(0,_op1); loadreg(1,_op2); @@ -325,7 +383,10 @@ implementation end. { $Log$ - Revision 1.4 2002-12-14 15:02:03 carl + Revision 1.5 2003-03-12 22:43:38 jonas + * more powerpc and generic fixes related to the new register allocator + + Revision 1.4 2002/12/14 15:02:03 carl * maxoperands -> max_operands (for portability in rautils.pas) * fix some range-check errors with loadconst + add ncgadd unit to m68k diff --git a/compiler/powerpc/agppcgas.pas b/compiler/powerpc/agppcgas.pas index d584cea04c..2ffbd42a76 100644 --- a/compiler/powerpc/agppcgas.pas +++ b/compiler/powerpc/agppcgas.pas @@ -174,6 +174,10 @@ unit agppcgas; if (symaddr <> refs_full) then s := s+')'+symaddr2str[symaddr]; + if (index.enum < firstreg) or (index.enum > lastreg) then + internalerror(20030312); + if (base.enum < firstreg) or (base.enum > lastreg) then + internalerror(200303123); if (index.enum=R_NO) and (base.enum<>R_NO) then begin if offset=0 then @@ -200,7 +204,11 @@ unit agppcgas; begin case o.typ of top_reg : - getopstr_jmp:=gas_reg2str[o.reg.enum]; + begin + if (o.reg.enum < R_0) or (o.reg.enum > lastreg) then + internalerror(200303121); + getopstr_jmp:=gas_reg2str[o.reg.enum]; + end; { no top_ref jumping for powerpc } top_const : getopstr_jmp:=tostr(o.val); @@ -234,8 +242,11 @@ unit agppcgas; begin case o.typ of top_reg: - getopstr:=gas_reg2str[o.reg.enum]; - { no top_ref jumping for powerpc } + begin + if (o.reg.enum < R_0) or (o.reg.enum > lastreg) then + internalerror(200303125); + getopstr:=gas_reg2str[o.reg.enum]; + end; top_const: getopstr:=tostr(longint(o.val)); top_ref: @@ -366,7 +377,10 @@ begin end. { $Log$ - Revision 1.20 2003-01-08 18:43:57 daniel + Revision 1.21 2003-03-12 22:43:38 jonas + * more powerpc and generic fixes related to the new register allocator + + Revision 1.20 2003/01/08 18:43:57 daniel * Tregister changed into a record Revision 1.19 2002/11/07 15:50:23 jonas diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index b7a4309793..af27331691 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -410,9 +410,9 @@ const procedure tcgppc.a_load_reg_reg(list : taasmoutput;fromsize, tosize : tcgsize;reg1,reg2 : tregister); begin - if reg1.enum<>R_INTREGISTER then + if (reg1.enum<>R_INTREGISTER) or (reg1.number = 0) then internalerror(200303101); - if reg2.enum<>R_INTREGISTER then + if (reg2.enum<>R_INTREGISTER) or (reg2.number = 0) then internalerror(200303102); if (reg1.number<>reg2.number) or (tcgsize2size[tosize] < tcgsize2size[fromsize]) or @@ -942,12 +942,13 @@ const { sum of the size necessary for local variables and the maximum possible } { combined size of ALL the parameters of a procedure called by the current } { one } - var regcounter,firstregfpu,firstreggpr, regcounter2 : TRegister; + var regcounter,firstregfpu,firstreggpr: TRegister; href : treference; usesfpr,usesgpr,gotgot : boolean; parastart : aword; offset : aword; r,r2,rsp:Tregister; + regcounter2: Tsuperregister; begin { we do our own localsize calculation } @@ -963,12 +964,11 @@ const r.number:=NR_R0; a_reg_alloc(list,r); { allocate registers containing reg parameters } - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R3; - for regcounter.enum := R_3 to R_10 do + r.enum := R_INTREGISTER; + for regcounter2 := RS_R3 to RS_R10 do begin - a_reg_alloc(list,regcounter2); - inc(regcounter2.number,NR_R1-NR_R0); + r.number:=regcounter2 shl 8; + a_reg_alloc(list,r); end; usesfpr:=false; @@ -981,17 +981,15 @@ const end; usesgpr:=false; - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R14; - for regcounter.enum:=R_14 to R_31 do + for regcounter2:=RS_R14 to RS_R31 do begin - if regcounter.enum in rg.usedbyproc then + if regcounter2 in rg.usedintbyproc then begin usesgpr:=true; - firstreggpr:=regcounter; + firstreggpr.enum := R_INTREGISTER; + firstreggpr.number := regcounter2 shl 8; break; end; - inc(regcounter2.number,NR_R1-NR_R0); end; { save link register? } @@ -1114,19 +1112,19 @@ const procedure tcgppc.g_return_from_proc_sysv(list : taasmoutput;parasize : aword); var - regcounter,firstregfpu,firstreggpr, regcounter2 : TRegister; + regcounter,firstregfpu,firstreggpr: TRegister; href : treference; usesfpr,usesgpr,genret : boolean; r,r2:Tregister; + regcounter2:Tsuperregister; begin { release parameter registers } - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R3; - for regcounter.enum := R_3 to R_10 do + r.enum := R_INTREGISTER; + for regcounter2 := RS_R3 to RS_R10 do begin - a_reg_dealloc(list,regcounter2); - inc(regcounter2.number,NR_R1-NR_R0); + r.number:=regcounter2 shl 8; + a_reg_dealloc(list,r); end; { AltiVec context restore, not yet implemented !!! } @@ -1140,17 +1138,15 @@ const end; usesgpr:=false; - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R14; - for regcounter.enum:=R_14 to R_30 do + for regcounter2:=RS_R14 to RS_R30 do begin - if regcounter.enum in rg.usedbyproc then + if regcounter2 in rg.usedintbyproc then begin usesgpr:=true; - firstreggpr:=regcounter2; + firstreggpr.enum:=R_INTREGISTER; + firstreggpr.number:=regcounter2 shl 8; break; end; - inc(regcounter2.number,NR_R1-NR_R0); end; { no return (blr) generated yet } @@ -1221,11 +1217,12 @@ const the save area right below the address the stackpointer point to. Returns the actual used save area size.} - var regcounter,firstregfpu,firstreggpr, regcounter2: TRegister; + var regcounter,firstregfpu,firstreggpr: TRegister; usesfpr,usesgpr: boolean; href : treference; offset: integer; - r:Tregister; + r,r2:Tregister; + regcounter2: Tsuperregister; begin usesfpr:=false; @@ -1238,17 +1235,15 @@ const end; usesgpr:=false; - r.enum := R_INTREGISTER; - r.number := NR_R13; - for regcounter.enum:=R_13 to R_31 do + for regcounter2:=RS_R13 to RS_R31 do begin - if regcounter.enum in rg.usedbyproc then + if regcounter2 in rg.usedintbyproc then begin usesgpr:=true; - firstreggpr:=r; + firstreggpr.enum:=R_INTREGISTER; + firstreggpr.number:=regcounter2 shl 8; break; end; - inc(r.number,NR_R1-NR_R0); end; offset:= 0; @@ -1277,16 +1272,16 @@ const end else begin - regcounter2 := firstreggpr; + r.enum:=R_INTREGISTER; + r.number:=NR_STACK_POINTER_REG; + r2 := firstreggpr; convert_register_to_enum(firstreggpr); for regcounter.enum := firstreggpr.enum to R_31 do begin offset:= offset - 4; - r.enum:=R_INTREGISTER; - r.number:=NR_STACK_POINTER_REG; reference_reset_base(href, r, offset); - list.concat(taicpu.op_reg_ref(A_STW, regcounter2, href)); - inc(regcounter2.number,NR_R1-NR_R0); + list.concat(taicpu.op_reg_ref(A_STW, r2, href)); + inc(r2.number,NR_R1-NR_R0); end; end; @@ -1299,11 +1294,12 @@ const {Generates code which restores used non-volatile registers from the save area right below the address the stackpointer point to.} - var regcounter,firstregfpu,firstreggpr,regcounter2: TRegister; + var regcounter,firstregfpu,firstreggpr: TRegister; usesfpr,usesgpr: boolean; href : treference; offset: integer; - r:Tregister; + r,r2:Tregister; + regcounter2: Tsuperregister; begin usesfpr:=false; @@ -1316,14 +1312,13 @@ const end; usesgpr:=false; - r.enum := R_INTREGISTER; - r.number := NR_R13; - for regcounter.enum:=R_13 to R_31 do + for regcounter2:=RS_R13 to RS_R31 do begin - if regcounter.enum in rg.usedbyproc then + if regcounter2 in rg.usedintbyproc then begin usesgpr:=true; - firstreggpr:=r; + firstreggpr.enum:=R_INTREGISTER; + firstreggpr.number:=regcounter2 shl 8; break; end; inc(r.number,NR_R1-NR_R0); @@ -1356,16 +1351,16 @@ const end else begin - regcounter2 := firstreggpr; + r.enum:=R_INTREGISTER; + r.number:=NR_STACK_POINTER_REG; + r2 := firstreggpr; convert_register_to_enum(firstreggpr); for regcounter.enum := firstreggpr.enum to R_31 do begin offset:= offset - 4; - r.enum:=R_INTREGISTER; - r.number:=NR_STACK_POINTER_REG; reference_reset_base(href, r, offset); - list.concat(taicpu.op_reg_ref(A_LWZ, regcounter2, href)); - inc(regcounter2.number,NR_R1-NR_R0); + list.concat(taicpu.op_reg_ref(A_LWZ, r2, href)); + inc(r2.number,NR_R1-NR_R0); end; end; @@ -1382,10 +1377,11 @@ const const macosLinkageAreaSize = 24; - var regcounter,regcounter2: TRegister; + var regcounter: TRegister; href : treference; registerSaveAreaSize : longint; r,r2,rsp:Tregister; + regcounter2: Tsuperregister; begin if (localsize mod 8) <> 0 then internalerror(58991); @@ -1401,12 +1397,11 @@ const a_reg_alloc(list,r); { allocate registers containing reg parameters } - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R3; - for regcounter.enum := R_3 to R_10 do + r.enum := R_INTREGISTER; + for regcounter2 := RS_R3 to RS_R10 do begin - a_reg_alloc(list,regcounter2); - inc(regcounter2.number,NR_R1-NR_R0); + r.number:=regcounter2 shl 8; + a_reg_alloc(list,r); end; {TODO: Allocate fp and altivec parameter registers also} @@ -1466,17 +1461,17 @@ const procedure tcgppc.g_return_from_proc_mac(list : taasmoutput;parasize : aword); var - regcounter, regcounter2: TRegister; + regcounter: TRegister; href : treference; r,r2,rsp:Tregister; + regcounter2: Tsuperregister; begin { release parameter registers } - regcounter2.enum := R_INTREGISTER; - regcounter2.number := NR_R3; - for regcounter.enum := R_3 to R_10 do + r.enum := R_INTREGISTER; + for regcounter2 := RS_R3 to RS_R10 do begin - a_reg_dealloc(list,regcounter2); - inc(regcounter2.number,NR_R1-NR_R0); + r.number := regcounter2 shl 8; + a_reg_dealloc(list,r); end; {TODO: Release fp and altivec parameter registers also} @@ -2192,7 +2187,10 @@ begin end. { $Log$ - Revision 1.72 2003-03-11 21:46:24 jonas + Revision 1.73 2003-03-12 22:43:38 jonas + * more powerpc and generic fixes related to the new register allocator + + Revision 1.72 2003/03/11 21:46:24 jonas * lots of new regallocator fixes, both in generic and ppc-specific code (ppc compiler still can't compile the linux system unit though) diff --git a/compiler/psub.pas b/compiler/psub.pas index e0fcab1525..af97f47452 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -364,9 +364,7 @@ implementation procinfo.aktproccode.concatlist(procinfo.aktexitcode); if not(cs_no_regalloc in aktglobalswitches) then begin -{$ifdef i386} procinfo.aktproccode.convert_registers; -{$endif} {$ifndef NoOpt} if (cs_optimize in aktglobalswitches) and { do not optimize pure assembler procedures } @@ -851,7 +849,10 @@ implementation end. { $Log$ - Revision 1.93 2003-03-08 08:59:07 daniel + Revision 1.94 2003-03-12 22:43:38 jonas + * more powerpc and generic fixes related to the new register allocator + + Revision 1.93 2003/03/08 08:59:07 daniel + $define newra will enable new register allocator + getregisterint will return imaginary registers with $newra + -sr switch added, will skip register allocation so you can see