Richard Henderson <rth7...@gmail.com> wrote on 22.04.2014 19:53:18: > On 04/22/2014 09:20 AM, Ulrich Weigand wrote: > > +#elif _CALL_ELF == 2 > > + /* In the ELFv2 ABI, we do not need to set up the TOC pointer in r2, > > + but instead we have to set up r12 to contain the destination address > > + when performing an indirect call. */ > > + TCGReg reg = arg; > > + if (const_arg) { > > + /* FIXME: we could use bl if we knew that the destination uses > > + the same TOC, and what its local entry point offset is. > > + For now, always perform an indirect call. */ > > + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, arg); > > + reg = TCG_REG_R12; > > + } else { > > + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R12, arg); > > + } > > + tcg_out32(s, MTSPR | RS(reg) | CTR); > > + tcg_out32(s, BCCTR | BO_ALWAYS | LK); > > Looks ok. > > Any chance we can get assurances on the same TOC from the compiler +linker?
Well, I wasn't quite sure how to determine what the target of such a call is: another snippet of generated code (which doesn't seem to use any TOC, unless I'm missing something ...), or compiled code (from which module? -- and when calling from generate code into compiled code, don't we need to set up the TOC in any case?) ... That said, GCC 4.8 (and we don't support anything older on powerpc64le-linux) defaults to -mcmodel=medium, so we ought to never see multiple TOCs in any single compiler-generated module. To enforce this in the linker, you can also use the --no-multi-toc linker option. > > -#ifndef __APPLE__ > > +#if !defined(__APPLE__) && _CALL_ELF != 2 > > /* First emit adhoc function descriptor */ > > tcg_out64(s, (uint64_t)s->code_ptr + 24); /* entry point */ > > s->code_ptr += 16; /* skip TOC and environment pointer */ > > The proper test here is #ifdef _CALL_AIX. Right. > Please check out > > git://github.com/rth7680/qemu.git tcg-ppc-merge > > which merges the ppc32 and ppc64 backends. I also started to > support the ELFv2 ABI. Ah, great! If you're working on this anyway, I'm fine with waiting on your implementation to be merged ... > I believe that you technically need > > #ifdef _CALL_AIX > # define LINK_AREA_SIZE (6 * SZR) > # define LR_OFFSET (1 * SZR) > # define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR) > +#elif defined(_CALL_ELF) && _CALL_ELF == 2 > +# define LINK_AREA_SIZE (4 * SZR) > +# define LR_OFFSET (1 * SZR) > +# define TCG_TARGET_CALL_STACK_OFFSET LINK_AREA_SIZE > > although we don't have helpers that will actually exercise 9 arguments. Ah, I missed that part. Yes, we can allocate smaller stack frames with ELFv2. (As you say, as long as no stack arguments are ever accessed, allocating a too-big stack frame doesn't really matter though.) Bye, Ulrich