From 99302af9a20c001bbc360d6c9721ce3fdd429530 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 16 Jun 2008 16:16:31 +0000 Subject: [PATCH] bfd/ * elf32-spu.c (struct spu_link_hash_table): Add extra_stack_space. (spu_elf_check_vma): Add extra_stack_space param, copy to htab. (spu_elf_auto_overlay): Use it. (RECURSE_UNMARK): Define as 0. (unmark_overlay_section): Heed RECURSE_UNMARK. * elf32-spu.h (spu_elf_check_vma): Update prototype. ld/ * emultempl/spuelf.em (extra_stack_space): New variable. (gld${EMULATION_NAME}_finish): Pass it to spu_elf_check_vma. (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Handle --extra-stack-space. * emultempl/spu_ovl.S: Mask interrupts during dma and update of overlay manager structures. * emultempl/spu_ovl.o: Regenerate. --- bfd/ChangeLog | 9 +++++++ bfd/elf32-spu.c | 22 ++++++++++++++--- bfd/elf32-spu.h | 2 +- ld/ChangeLog | 10 ++++++++ ld/emultempl/spu_ovl.S | 55 +++++++++++++++++++++++++++++++++++------ ld/emultempl/spu_ovl.o | Bin 1500 -> 1608 bytes ld/emultempl/spuelf.em | 20 +++++++++++++-- 7 files changed, 104 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 67534713ece..760914d2faa 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2008-06-17 Alan Modra + + * elf32-spu.c (struct spu_link_hash_table): Add extra_stack_space. + (spu_elf_check_vma): Add extra_stack_space param, copy to htab. + (spu_elf_auto_overlay): Use it. + (RECURSE_UNMARK): Define as 0. + (unmark_overlay_section): Heed RECURSE_UNMARK. + * elf32-spu.h (spu_elf_check_vma): Update prototype. + 2008-06-12 DJ Delorie * elf32-m32c.c (ELF_MACHINE_ALT1): Define as EM_M32C_OLD. diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index eac2e85a12e..590ebd5b381 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -325,6 +325,11 @@ struct spu_link_hash_table unsigned int overlay_fixed; /* Local store --auto-overlay should reserve for stack and heap. */ unsigned int reserved; + /* If reserved is not specified, stack analysis will calculate a value + for the stack. This parameter adjusts that value to allow for + negative sp access (the ABI says 2000 bytes below sp are valid, + and the overlay manager uses some of this area). */ + int extra_stack_space; /* Count of overlay stubs needed in non-overlay area. */ unsigned int non_ovly_stub; @@ -1548,6 +1553,7 @@ spu_elf_check_vma (struct bfd_link_info *info, unsigned int hi, unsigned int overlay_fixed, unsigned int reserved, + int extra_stack_space, void (*spu_elf_load_ovl_mgr) (void), FILE *(*spu_elf_open_overlay_script) (void), void (*spu_elf_relink) (void)) @@ -1562,6 +1568,7 @@ spu_elf_check_vma (struct bfd_link_info *info, htab->local_store = hi + 1 - lo; htab->overlay_fixed = overlay_fixed; htab->reserved = reserved; + htab->extra_stack_space = extra_stack_space; htab->spu_elf_load_ovl_mgr = spu_elf_load_ovl_mgr; htab->spu_elf_open_overlay_script = spu_elf_open_overlay_script; htab->spu_elf_relink = spu_elf_relink; @@ -2923,6 +2930,11 @@ mark_overlay_section (struct function_info *fun, return TRUE; } +/* If non-zero then unmark functions called from those within sections + that we need to unmark. Unfortunately this isn't reliable since the + call graph cannot know the destination of function pointer calls. */ +#define RECURSE_UNMARK 0 + struct _uos_param { asection *exclude_input_section; asection *exclude_output_section; @@ -2950,9 +2962,10 @@ unmark_overlay_section (struct function_info *fun, || fun->sec->output_section == uos_param->exclude_output_section) excluded = 1; - uos_param->clearing += excluded; + if (RECURSE_UNMARK) + uos_param->clearing += excluded; - if (uos_param->clearing) + if (RECURSE_UNMARK ? uos_param->clearing : excluded) { fun->sec->linker_mark = 0; if (fun->rodata) @@ -2963,7 +2976,8 @@ unmark_overlay_section (struct function_info *fun, if (!unmark_overlay_section (call->fun, info, param)) return FALSE; - uos_param->clearing -= excluded; + if (RECURSE_UNMARK) + uos_param->clearing -= excluded; return TRUE; } @@ -3574,7 +3588,7 @@ spu_elf_auto_overlay (struct bfd_link_info *info, sum_stack_param.overall_stack = 0; if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE)) goto err_exit; - htab->reserved = sum_stack_param.overall_stack + 2000; + htab->reserved = sum_stack_param.overall_stack + htab->extra_stack_space; } fixed_size += htab->reserved; fixed_size += htab->non_ovly_stub * OVL_STUB_SIZE; diff --git a/bfd/elf32-spu.h b/bfd/elf32-spu.h index e0141d57234..ec443fd99f8 100644 --- a/bfd/elf32-spu.h +++ b/bfd/elf32-spu.h @@ -62,5 +62,5 @@ extern int spu_elf_size_stubs (struct bfd_link_info *, extern bfd_boolean spu_elf_build_stubs (struct bfd_link_info *, int); extern asection *spu_elf_check_vma (struct bfd_link_info *, int, unsigned int, unsigned int, unsigned int, - unsigned int, void (*) (void), + unsigned int, int, void (*) (void), FILE *(*) (void), void (*) (void)); diff --git a/ld/ChangeLog b/ld/ChangeLog index c29fc357dbe..98fe7b2a472 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2008-06-17 Alan Modra + + * emultempl/spuelf.em (extra_stack_space): New variable. + (gld${EMULATION_NAME}_finish): Pass it to spu_elf_check_vma. + (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS, + PARSE_AND_LIST_ARGS_CASES): Handle --extra-stack-space. + * emultempl/spu_ovl.S: Mask interrupts during dma and update of + overlay manager structures. + * emultempl/spu_ovl.o: Regenerate. + 2008-06-16 Hans-Peter Nilsson * ld.texinfo (@node MMIX): For the __.MMIX.start. prefix, only diff --git a/ld/emultempl/spu_ovl.S b/ld/emultempl/spu_ovl.S index 92304b219e1..509397a6090 100644 --- a/ld/emultempl/spu_ovl.S +++ b/ld/emultempl/spu_ovl.S @@ -67,11 +67,13 @@ #define rv5 reserved4 #define cgshuf reserved4 #define newovl reserved4 +#define irqtmp1 reserved4 +#define irqtmp2 reserved4 #define reserved5 $79 #define target reserved5 -#define save1 $72 +#define save1 $74 #define rv4 save1 #define rv7 save1 #define tagid save1 @@ -87,7 +89,7 @@ #define oldovl save2 #define newvma save2 -#define save3 $74 +#define save3 $72 #define rv1 save3 #define ea64 save3 #define buf3 save3 @@ -95,6 +97,8 @@ #define newmap save3 #define oldmask save3 +#define save4 $71 +#define irq_stat save4 .text .align 4 @@ -140,7 +144,12 @@ __ovly_return: #nop; lnop #nop lqx vma, tab1, off1 # 1,6 8 +#ifdef OVLY_IRQ_SAVE + nop + stqd save4, -64($sp) # 1,6 9 +#else #nop; lnop +#endif #nop; lnop #nop; lnop #nop; lnop @@ -168,7 +177,9 @@ ovly_ret9: * On entry $75 points to a word consisting of the overlay index in * the top 14 bits, and the target address in the bottom 18 bits. * - * Sets up $lr to return via __ovly_return. + * Sets up $lr to return via __ovly_return. If $lr is already set + * to return via __ovly_return, don't change it. In that case we + * have a tail call from one overlay function to another. * Updates __ovly_current. */ .align 3 @@ -245,7 +256,11 @@ __ovly_load: or rv7, rv4, rv6 # 0,2 16 lqd save2, -32($sp) # 1,6 16 andi present2, size2, 1 # 0,2 17 +#ifdef OVLY_IRQ_SAVE + stqd save4, -64($sp) # 1,6 17 +#else lnop # 1,0 17 +#endif selb $lr, rv7, $lr, rv5 # 0,2 18 lqd save1, -16($sp) # 1,6 18 #nop @@ -268,9 +283,19 @@ ovly_load9: .type __ovly_load_event, @function __ovly_load_event: do_load: +#ifdef OVLY_IRQ_SAVE + ila irqtmp1, do_load10 # 0,2 -5 + rotqbyi sz, vma, 8 # 1,4 -5 #nop - rotqbyi sz, vma, 8 # 1,4 0 + rdch irq_stat, $SPU_RdMachStat # 1,6 -4 #nop + bid irqtmp1 # 1,4 -3 +do_load10: + nop +#else +#nop + rotqbyi sz, vma, 8 # 1,4 0 +#endif rotqbyi osize, vma, 4 # 1,4 1 #nop lqa ea64, _EAR_ # 1,6 2 @@ -410,14 +435,30 @@ __ovly_xfer_loop: #nop; lnop andc pbit, pbit, zovl # 0,2 74 lqd save2, -32($sp) # 1,6 74 +#ifdef OVLY_IRQ_SAVE + ila irqtmp2, do_load90 # 0,2 75 +#lnop + andi irq_stat, irq_stat, 1 # 0,2 76 +#lnop +#else #nop; lnop #nop; lnop +#endif andc oldvma, oldvma, pbit # 0,2 77 lqd save1, -16($sp) # 1,6 77 -#nop; lnop - nop + nop # 0,0 78 +#lnop +#nop stqx oldvma, tab5, off5 # 1,6 79 +#nop +#ifdef OVLY_IRQ_SAVE + binze irq_stat, irqtmp2 # 1,4 80 +do_load90: +#nop + lqd save4, -64($sp) # 1,6 84 +#else #nop; lnop +#endif .global _ovly_debug_event .type _ovly_debug_event, @function @@ -425,6 +466,6 @@ _ovly_debug_event: nop /* Branch to target address. */ do_load99: - bi target # 1,4 81 + bi target # 1,4 81/85 .size __ovly_load, . - __ovly_load diff --git a/ld/emultempl/spu_ovl.o b/ld/emultempl/spu_ovl.o index 4fe2b25c2bdc93c2b4d2af4dcdf72675d210e415..5121b87aa623795d802dc4241d8b0c2787929854 100644 GIT binary patch literal 1608 zcmb7EO-vI}5S}d*iW+`e5=p$YVY@ZP5PpggHEAVLN@=U22XAXj7d%uUWg(E5u&5W~ zL1V8TdVs6(;Dw8FFoDv-MPrQdq8{{OV$`Syll7a|x25XAILYkH_ue<(n>V}d(y7F0 z#idZq6xxrxZoy@Wy|8#5BoDc3Tuu~MLwkqUXGv>xH#Ivs$KSXB!$f0|H0B52N1GZ^Xl>XMH}`qF^cvuAda= zoK)m`u%Z;3HU>Q*Vtv$>dM%0#*za~CPqbv$`D|jXprtPRvWa0o#R;57(qfTiEgAE! zR02iM*sXgaa=-CFu_ZZ7{v=|>0d2HZUi?E7PL~^r4_;9{bSFx%`Tr-IbH~s*1Ydys4c7LVHo#7@3BB}?-(5S z*q5NFn12$px!0Cf(cj+KHBw7QEVaa1JeP}dF3?GJ(!|Ea{#C56Z}I(cb~&hqM#7jE zV}2jhGrM@jOlJ_yd^KKnvb>Q?_n5|lNj=%LnWmo1>@5AC;S}*LHp#LmkxQl`v`cUR zv2l09{Tg`=&UFf$_x8axi5n1Mt|%V$#$2|;a1Z=nypCNCGIB-n=z}}v=y9xTyx|er zI*YYtcq^Ry|-?zyQYh9Q+3Z7~>4WPl2i!+RE2DJdeDWvA4Q^Q|^f- zk>7>SVC$~jzYi?>k@&$Me9XIQd`Z|-)QWxtU)S^V`b^q1jr>*8^@*uEFg>4J)Fg$DsATCTAd9bEu9QII+G*lx&ZH`YB75D+=45wV^ zODWEEW1f4^Pn{gsB|kGasmmHspEWXbQ<5j{i5a%JZQK3?gn8BS1-x?Se;jjDIOq2T ao>zXS%7tCN0=|!R@XnNnb?dTL`T7eH+C7K> literal 1500 zcmb7EKTH#06n|GJ6hZ#9B$Bwap*@H(4N@SWCPfmol(r`5z;?9sfT2QDt^^Vi4qar? z#5x$KF7B=@N{j=gg_!8zVuB938550hFgbtk>vvFaFuvs7`~B|ye((G4yK6VbW7idj zLPw#{IpCTbj@zO)Ag;aSBIl8of#RrZ?{Ire8THPFMjLZIp#>QunhbxWMEDckY)kgU z2F;$W;X+zwTo<#TsP4N5y_+9C2pWrpgpBRAFONv-0d^b>m zw$x`*G-Q1~2)|V0UAOeuc0o-nc=Xtqmm=(|Cp8-0RO1o1zv3&pCbu4m%KMA>icRq` z^2SjsF8ADouXrZXVaLC#A()SAU=sz8Bc*EvTio znP)=7{mXCFy)KVhxl#y}wx_;C;Vt{IhcWD1DK=i=&_jv2v`c&*wO(Qr=Y3rGyJR2xxz~bJC9gw8IJ}}9 zUs%g=5$QtyOV@F%0jkcs#7KrckE_GJiLsBdtv>KZB=3v&$IsG)lxqS}{cBuaF_K}= zv-w{Y<`Ww5nt6ioTDGPgfN?95*S9&Jr?-Y*08S%0SkJ%qH%t)BuOcf<5X^5N50M`J zov$HFE15NIHlNGsiv|gj(~S{IFKL;jWV(8X(Fly9y*j7o&|AvdnvtUxoOxbB=lP`U