diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-05-30 21:12:57 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-05-30 21:12:57 +0000 |
commit | 585c02b95e1e192a626d9a56a97a5acc27b4c1c3 (patch) | |
tree | 0c5eb1ec8cdc5b860f11ea21b0d9b1a525efc0f8 /compiler/arm/cpupara.pas | |
parent | e0d417123e477a6c50ff67c1c7ae13212279a102 (diff) | |
download | fpc-585c02b95e1e192a626d9a56a97a5acc27b4c1c3.tar.gz |
* changed tprocdef.funcretloc[] from a tlocation into a tcgpara so it can
represent complex locations (required for full x86-64 ABI support,
which is not yet implemented) -> lots of special result handling
code has been removed and replaced by the parameter handling
routines
+ added support for composite parameters (and hence function
results) to tcg.a_load_ref_cgpara() (so it can be used for
handling, e.g., 64 bit parameters on 32 bit platforms)
* the above fixed writing past the end of allocated memory when
handling records returned in registers on x86-64 whose size is
not a multiple of 8 bytes (mantis #16357)
- removed the x86-64 and PPC specific versions of a_load_ref_cgpara(),
as they are now handled correctly by the generic version
* moved the responsibility of allocating tcgpara cpu registers
(using paramanager.allocparaloc()) from the callers of
cg.a_load*_cgpara() to the cg.a_load*_cgpara() methods
themselves (so the register allocation can be done efficiently
when dealing with function results)
* for the above, renamed paramanager.alloc/freeparaloc() to
paramanager.alloc/freecgpara(), and use paramanager.allocparaloc()
to allocate individual pcgparalocations instead
* fixed the register size of SSE2 function result registers for
x86-64 (when used for floating point), which results in removing
a few superfluous "movs? %xmm0,%xmm0" instructions
* fixed compilation of paramanagers of avr, m68k and mips after r13695
and also updated them for these new changes
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@15350 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/arm/cpupara.pas')
-rw-r--r-- | compiler/arm/cpupara.pas | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 367ca94738..0f0b9d71ad 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -42,7 +42,7 @@ unit cpupara; procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tlocation;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; private procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword); function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; @@ -451,32 +451,45 @@ unit cpupara; end; - function tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tlocation; + function tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; var + paraloc : pcgparalocation; retcgsize : tcgsize; begin - { Constructors return self instead of a boolean } - if (p.proctypeoption=potype_constructor) then - retcgsize:=OS_ADDR - else - retcgsize:=def_cgsize(def); - - location_reset(result,LOC_INVALID,OS_NO); - result.size:=retcgsize; - + result.init; + result.alignment:=get_para_align(p.proccalloption); { void has no location } if is_void(def) then begin - location_reset(result,LOC_VOID,OS_NO); + paraloc:=result.add_location; + result.size:=OS_NO; + result.intsize:=0; + paraloc^.size:=OS_NO; + paraloc^.loc:=LOC_VOID; exit; end; + { Constructors return self instead of a boolean } + if (p.proctypeoption=potype_constructor) then + begin + retcgsize:=OS_ADDR; + result.intsize:=sizeof(pint); + end + else + begin + retcgsize:=def_cgsize(def); + result.intsize:=def.size; + end; + result.size:=retcgsize; { Return is passed as var parameter } if ret_in_param(def,p.proccalloption) then begin - result.loc:=LOC_REFERENCE; - result.size:=retcgsize; + paraloc:=result.add_location; + paraloc^.loc:=LOC_REFERENCE; + paraloc^.size:=retcgsize; exit; end; + + paraloc:=result.add_location; { Return in FPU register? } if def.typ=floatdef then begin @@ -488,18 +501,20 @@ unit cpupara; OS_64, OS_F64: begin - { low } - result.loc:=LOC_REGISTER; - result.register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG; - result.register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG; - result.size:=OS_64; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG; + paraloc^.size:=OS_32; + paraloc:=result.add_location; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG; + paraloc^.size:=OS_32; end; OS_32, OS_F32: begin - result.loc:=LOC_REGISTER; - result.register:=NR_FUNCTION_RETURN_REG; - result.size:=OS_32; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RETURN_REG; + paraloc^.size:=OS_32; end; else internalerror(2005082603); @@ -507,8 +522,9 @@ unit cpupara; end else begin - result.loc:=LOC_FPUREGISTER; - result.register:=NR_FPU_RESULT_REG; + paraloc^.loc:=LOC_FPUREGISTER; + paraloc^.register:=NR_FPU_RESULT_REG; + paraloc^.size:=retcgsize; end; end { Return in register } @@ -516,15 +532,19 @@ unit cpupara; begin if retcgsize in [OS_64,OS_S64] then begin - { low } - result.loc:=LOC_REGISTER; - result.register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG; - result.register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG; + paraloc^.size:=OS_32; + paraloc:=result.add_location; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG; + paraloc^.size:=OS_32; end else begin - result.loc:=LOC_REGISTER; - result.register:=NR_FUNCTION_RETURN_REG; + paraloc^.loc:=LOC_REGISTER; + paraloc^.register:=NR_FUNCTION_RETURN_REG; + paraloc^.size:=retcgsize; end; end; end; |