diff options
author | janbruns <janbruns@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-04-19 14:36:55 +0000 |
---|---|---|
committer | janbruns <janbruns@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-04-19 14:36:55 +0000 |
commit | 20b60766016dedfe74ca1f02edde4d66e4f590f6 (patch) | |
tree | a58d13eccc5570a8ce50aef73298e33bc2e8cc8b | |
parent | 5bd5308c126e1cdeac24d7f1830fe834c3c179c4 (diff) | |
download | fpc-20b60766016dedfe74ca1f02edde4d66e4f590f6.tar.gz |
ARM: Add rg-support for the new virtual instructions
The virtual instructions are still unused, so this change shouldn't influence the actual compiler behaviour.
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/janbruns@10715 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | initial/compiler/arm/aasmcpu.pas | 67 | ||||
-rw-r--r-- | initial/compiler/arm/rgcpu.pas | 68 |
2 files changed, 131 insertions, 4 deletions
diff --git a/initial/compiler/arm/aasmcpu.pas b/initial/compiler/arm/aasmcpu.pas index 7d6cab7f6c..7461e86d1f 100644 --- a/initial/compiler/arm/aasmcpu.pas +++ b/initial/compiler/arm/aasmcpu.pas @@ -499,6 +499,21 @@ implementation end; +{$IFDEF USE_VIRTUAL_INSTRUCTIONS} + + function spilling_create_load(const ref:treference;r:tregister):Taicpu; + begin + result:=taicpu.op_reg_ref(A_ZZZ_VIRTUALUNSPILL,r,ref); + end; + + + function spilling_create_store(r:tregister; const ref:treference):Taicpu; + begin + result:=taicpu.op_reg_ref(A_ZZZ_VIRTUALSPILL,r,ref); + end; + +{$ELSE don't USE_VIRTUAL_INSTRUCTIONS} + function spilling_create_load(const ref:treference;r:tregister):Taicpu; begin case getregtype(r) of @@ -530,6 +545,8 @@ implementation end; end; +{$ENDIF} + function taicpu.spilling_get_operation_type(opnr: longint): topertype; begin @@ -573,8 +590,56 @@ implementation else { check for pre/post indexed } result := operand_read; + + A_ZZZ_VIRTUALSAVE : + begin + // when storing a reg, the reg to be stored is read, + // temps might be written, refs read + if opnr=0 + then result := operand_read + else begin + if (oper[opnr]^.typ = top_reg) + or (oper[opnr]^.typ = top_regset) then result := operand_write + else result := operand_read; + end; + end; + + A_ZZZ_VIRTUALLOAD : + begin + // same as virtualstore, only that the reg is written (read from mem) + if opnr=0 + then result := operand_write + else begin + if (oper[opnr]^.typ = top_reg) + or (oper[opnr]^.typ = top_regset) then result := operand_write + else result := operand_read; + end; + end; + + A_ZZZ_VIRTUALCOPY : + begin + // if this instrctuction has reg-operands, they're + // used as temps, so they're virtually only written to + if (oper[opnr]^.typ = top_reg) + or (oper[opnr]^.typ = top_regset) then result := operand_write + else result := operand_read; + end; + + A_ZZZ_VIRTUALSPILL : + begin + // we won't modify registers when spilling + result := operand_read; + end; + + A_ZZZ_VIRTUALUNSPILL : + begin + // we read the register back, so the register is written + if opnr=0 then result := operand_write + else result := operand_read; + end; + else - internalerror(200403151); + internalerror(2008041802); end; end; diff --git a/initial/compiler/arm/rgcpu.pas b/initial/compiler/arm/rgcpu.pas index 58b8d9cc43..0676840558 100644 --- a/initial/compiler/arm/rgcpu.pas +++ b/initial/compiler/arm/rgcpu.pas @@ -41,6 +41,8 @@ unit rgcpu; trgintcpu = class(trgcpu) procedure add_cpu_interferences(p : tai);override; + + procedure add_regset_edges(s : Tcpuregisterset; v:Tsuperregister); virtual; end; implementation @@ -157,9 +159,25 @@ unit rgcpu; end; + + procedure trgintcpu.add_regset_edges(s : Tcpuregisterset; v:Tsuperregister); + const num2reg : array[0..15] of Tsuperregister = (RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10,RS_R11,RS_R12,RS_R13,RS_R14,RS_R15); + var i : longint; r : Tsuperregister; + begin + for i := 0 to 15 do begin + r := num2reg[i]; + if (r in s) then begin + add_edge(r,v); + add_edge(v,r); + end; + end; + end; + + + procedure trgintcpu.add_cpu_interferences(p : tai); var - r : tregister; + r : tregister; i,j : longint; begin if p.typ=ait_instruction then begin @@ -181,6 +199,13 @@ unit rgcpu; A_LDR, A_LDRH, A_STRH: + { + Did this happen? + Where/why, and if so, why disallow? + For now, I (JB) leave this here, but I think this "problem" + should be fixed elsewhere. + } + { don't mix up the framepointer and stackpointer with pre/post indexed operations } if (taicpu(p).oper[1]^.typ=top_ref) and (taicpu(p).oper[1]^.ref^.addressmode in [AM_PREINDEXED,AM_POSTINDEXED]) then @@ -192,8 +217,45 @@ unit rgcpu; if current_procinfo.framepointer<>r then add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),getsupreg(r)); end; - end; - end; + + A_ZZZ_VIRTUALLOAD, + A_ZZZ_VIRTUALSAVE, + A_ZZZ_VIRTUALCOPY : + begin + { if the instruction contains tempregs, make sure they're + all diffrent, also from the reg to load/store. regs given + in the ref may probably be shared, if they aren't needed + anymore. + } + for i := taicpu(p).ops-1 downto 0 do begin + + if (taicpu(p).oper[i]^.typ in [top_reg,top_regset]) then begin + + for j := taicpu(p).ops-1 downto 0 do begin + + if not(i=j) and (taicpu(p).oper[j]^.typ=top_reg) then begin + if (taicpu(p).oper[i]^.typ=top_reg) + then add_edge( getsupreg( taicpu(p).oper[i]^.reg ) ,getsupreg(taicpu(p).oper[j]^.reg)) + else add_regset_edges( taicpu(p).oper[i]^.regset^,getsupreg(taicpu(p).oper[j]^.reg)); + end; + + end; + end; + if taicpu(p).opcode=A_ZZZ_VIRTUALCOPY then begin + { Maybe it's needed to add additional constraints + for copying refs, here. I'm unsure what to do + if tempregs are equal to refregs of both refs. + We should probably not generate that case, or + maybe concatcopy will be able to deal with this + situation. + } + end; + end; + end; + A_ZZZ_VIRTUALSPILL, + A_ZZZ_VIRTUALUNSPILL : ; // actually no known constraints + end; {case instr} + end; {if tai-instr} end; |