Index: libitm/config/darwin/powerpc/sjlj.S =================================================================== --- libitm/config/darwin/powerpc/sjlj.S (revision 0) +++ libitm/config/darwin/powerpc/sjlj.S (revision 0) @@ -0,0 +1,335 @@ +/* Copyright (C) 2011 Free Software Foundation, Inc. + Contributed by Iain Sandoe . + + This file is part of the GNU Transactional Memory Library (libitm). + + Libitm is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libitm is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + + +#if defined(__ppc64__) +#define MODE_CHOICE(x, y) y +#else +#define MODE_CHOICE(x, y) x +#endif + +#define MACHINE MODE_CHOICE(ppc7400,ppc64) +#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ +#define GPR_BYTES MODE_CHOICE(4,8) /* size of a GPR in bytes */ +#define FPR_BYTES 8 /* size of a FPR in bytes */ +#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ + +#define cmpg MODE_CHOICE(cmpw, cmpd) +#define lg MODE_CHOICE(lwz, ld) +#define sg MODE_CHOICE(stw, std) +#define lgx MODE_CHOICE(lwzx, ldx) +#define sgx MODE_CHOICE(stwx, stdx) +#define lgu MODE_CHOICE(lwzu, ldu) +#define sgu MODE_CHOICE(stwu, stdu) +#define lgux MODE_CHOICE(lwzux, ldux) +#define sgux MODE_CHOICE(stwux, stdux) +#define lgwa MODE_CHOICE(lwz, lwa) + +/* Stack frame constants. */ +#define RED_ZONE_SIZE MODE_CHOICE(224,288) +#define LINKAGE_SIZE MODE_CHOICE(24,48) +#define SAVED_LR_OFFSET MODE_CHOICE(8,16) +#define SAVED_CR_OFFSET MODE_CHOICE(4,8) + +/* We will assume that the code is to be built for a processor with Altivec. + + TODO 1: + For Darwin 8 or earlier, which might be on hardware with either G3 or G4/G5, + then the vecSave code here would ideally need to be made conditional (for + m32) on __cpu_has_altivec from the system framework (as is done in Darwin`s + save_world () routine in libgcc). I.E. One needs to check for Altivec at + runtime. As things stand, it should be fine on Darwin 8/9 with G4/G5. */ + +/* TODO 2: + Generate eh_frame data. */ + +# define VECS_SIZ 12*16 + +#ifdef __ppc64__ +# define VEC_PAD 0 +#else +# define VEC_PAD 8 +#endif + +#define RESTOC GPR_BYTES +#define SAVPC GPR_BYTES +#define FPSCR FPR_BYTES +#define SAVSP GPR_BYTES +#define SAVCR 4 +#ifdef __ppc64__ +/* Add for gpr13 and the VRsave. */ +# define RZADD 12 +#else + /* which are included in red zone at m32. */ +# define RZADD 0 +#endif + +#define GTMSIZ (VECS_SIZ + VEC_PAD + RESTOC + SAVPC + FPSCR + SAVCR + SAVSP\ + + RZADD + RED_ZONE_SIZE) + +/* The stack frame components for the call to GTM_begin_transaction. + + We call GTM_begin_transaction (uint32_t, gtm_jmpbuf*). So we must provide + space for those params in the stack frame so that the callee can save them + there if it wants to. +*/ + +#define NEXT_FRAME (LINKAGE_SIZE + 2 * GPR_BYTES) + +#define FRAME_SIZE (((NEXT_FRAME + GTMSIZ + 15) / 16) * 16) + +/* From the start of the gtm_jmpbuf. */ +#define VEC_OFF 0 +#define TOC_OFF (VECS_SIZ + VEC_PAD) +#define PC_OFF (TOC_OFF + GPR_BYTES) +#define FPSCRS_OFF (PC_OFF + GPR_BYTES) +#define SP_OFF (FPSCRS_OFF + FPR_BYTES) +#define CR_OFF (SP_OFF + GPR_BYTES) +#define VRSAVE_OFF (CR_OFF + 4) +#define GPRS_OFF (VRSAVE_OFF + 4) +#define FPRS_OFF (GPRS_OFF + 19 * GPR_BYTES) + + .text + + .machine MACHINE + + .align 4 + + /* _ITM_beginTransaction(uint32_t, ...) */ + + .globl __ITM_beginTransaction +__ITM_beginTransaction: + + mfcr r0 + + /* ??? Test r3 for pr_hasNoFloatUpdate and skip the fp save. + This is not yet set by the compiler. */ + + stfd f14,-144(r1) + stfd f15,-136(r1) + stfd f16,-128(r1) + stfd f17,-120(r1) + stfd f18,-112(r1) + stfd f19,-104(r1) + stfd f20,-96(r1) + stfd f21,-88(r1) + stfd f22,-80(r1) + stfd f23,-72(r1) + stfd f24,-64(r1) + stfd f25,-56(r1) + stfd f26,-48(r1) + stfd f27,-40(r1) + stfd f28,-32(r1) + stfd f29,-24(r1) + stfd f30,-16(r1) + mffs f0 + stfd f31,-8(r1) + +#ifndef __ppc64__ + /* This might not be the best approach - stmw could be slower than the + one-by-one store. */ + stmw r13,-220(r1) +#else + sg r14,(-288 + 0 * GPR_BYTES)(r1) + sg r15,(-288 + 1 * GPR_BYTES)(r1) + sg r16,(-288 + 2 * GPR_BYTES)(r1) + sg r17,(-288 + 3 * GPR_BYTES)(r1) + sg r18,(-288 + 4 * GPR_BYTES)(r1) + sg r19,(-288 + 5 * GPR_BYTES)(r1) + sg r20,(-288 + 6 * GPR_BYTES)(r1) + sg r21,(-288 + 7 * GPR_BYTES)(r1) + sg r22,(-288 + 8 * GPR_BYTES)(r1) + sg r23,(-288 + 9 * GPR_BYTES)(r1) + sg r24,(-288 + 10 * GPR_BYTES)(r1) + sg r25,(-288 + 11 * GPR_BYTES)(r1) + sg r26,(-288 + 12 * GPR_BYTES)(r1) + sg r27,(-288 + 13 * GPR_BYTES)(r1) + sg r28,(-288 + 14 * GPR_BYTES)(r1) + sg r29,(-288 + 15 * GPR_BYTES)(r1) + sg r30,(-288 + 16 * GPR_BYTES)(r1) + sg r31,(-288 + 17 * GPR_BYTES)(r1) +#endif + /* Filled the red zone - so now we need to allocate the frame. */ + mr r5,r1 /* copy SP. */ + sgu r1,-FRAME_SIZE(r1) /* Allocate stack frame */ + addi r4,r5,-GTMSIZ /* Point to the jump buffer. */ + +/* sg r2,TOC_OFF(r4) not needed on Darwin. */ +#ifdef __ppc64__ + /* The ABI doc is slighlty ambiguous about r13 m64 - it is reserved for + for TLS, but also stated to be call-saved (TLS is not implemented + for any ppc Darwin variant). */ + sg r13,GPRS_OFF(r4) +#endif + stfd f0,FPSCRS_OFF(r4) + sg r5,SP_OFF(r4) + stw r0,CR_OFF(r4) + mflr r0 + sg r0,PC_OFF(r4) + sg r0,SAVED_LR_OFFSET(r5) + + /* ??? Determine when VRs not present. */ + /* ??? Test r3 for pr_hasNoVectorUpdate and skip the vr save. + This is not yet set by the compiler. */ + + mfspr r0,VRsave + addi r5,r4,VECS_SIZ-16 /* Now r5 points at V31 save. */ + stw r0,VRSAVE_OFF(r4) + addi r4,r5,-16 /* now r4 points to V30 save. */ + + stvx v31,0,r5 + addi r5,r5,-32 + stvx v30,0,r4 + addi r4,r4,-32 + stvx v29,0,r5 + addi r5,r5,-32 + stvx v28,0,r4 + addi r4,r4,-32 + stvx v27,0,r5 + addi r5,r5,-32 + stvx v26,0,r4 + addi r4,r4,-32 + stvx v25,0,r5 + addi r5,r5,-32 + stvx v24,0,r4 + addi r4,r4,-32 + stvx v23,0,r5 + addi r5,r5,-32 + stvx v22,0,r4 + addi r4,r4,-32 + stvx v21,0,r5 + stvx v20,0,r4 /* r4 back to the start. */ + + /* r3 is as per entry, r4 points at our gtm_jmpbuf. */ + /* GTM_begin_transaction (uint32_t prop, gtm_jmpbuf *bf) */ + bl _GTM_begin_transaction + nop + + lg r0,(SAVED_LR_OFFSET + FRAME_SIZE)(r1) + mtlr r0 + addi r1, r1, FRAME_SIZE + blr + + /* End of _ITM_beginTransaction. */ + + /* uint32_t GTM_longjmp (uint32_t, const gtm_jmpbuf *, uint32_t) */ + + .private_extern _GTM_longjmp +_GTM_longjmp: + + /* ??? Determine when VRs not present. */ + /* ??? Test r5 for pr_hasNoVectorUpdate and skip the vr restore. + This is not yet set by the compiler. */ + + mr r14,r4 + lwz r0,VRSAVE_OFF(r4) + addi r15,r4,16 + + lvx v20,0,r14 + addi r14,r14,32 + lvx v21,0,r15 + addi r15,r15,32 + lvx v22,0,r14 + addi r14,r14,32 + lvx v23,0,r15 + addi r15,r15,32 + lvx v24,0,r14 + addi r14,r14,32 + lvx v25,0,r15 + addi r15,r15,32 + lvx v26,0,r14 + addi r14,r14,32 + lvx v27,0,r15 + addi r15,r15,32 + lvx v28,0,r14 + addi r14,r14,32 + lvx v29,0,r15 + addi r15,r15,32 + lvx v30,0,r14 + addi r14,r14,32 + lvx v31,0,r15 + + mtspr VRsave,r0 /* Restored... */ + +#ifndef __ppc64__ + lmw r13,GPRS_OFF(r4) +#else + lg r13,(GPRS_OFF + 0 * GPR_BYTES)(r4) + lg r14,(GPRS_OFF + 1 * GPR_BYTES)(r4) + lg r15,(GPRS_OFF + 2 * GPR_BYTES)(r4) + lg r16,(GPRS_OFF + 3 * GPR_BYTES)(r4) + lg r17,(GPRS_OFF + 4 * GPR_BYTES)(r4) + lg r18,(GPRS_OFF + 5 * GPR_BYTES)(r4) + lg r19,(GPRS_OFF + 6 * GPR_BYTES)(r4) + lg r20,(GPRS_OFF + 7 * GPR_BYTES)(r4) + lg r21,(GPRS_OFF + 8 * GPR_BYTES)(r4) + lg r22,(GPRS_OFF + 9 * GPR_BYTES)(r4) + lg r23,(GPRS_OFF + 10 * GPR_BYTES)(r4) + lg r24,(GPRS_OFF + 11 * GPR_BYTES)(r4) + lg r25,(GPRS_OFF + 12 * GPR_BYTES)(r4) + lg r26,(GPRS_OFF + 13 * GPR_BYTES)(r4) + lg r27,(GPRS_OFF + 14 * GPR_BYTES)(r4) + lg r28,(GPRS_OFF + 15 * GPR_BYTES)(r4) + lg r29,(GPRS_OFF + 16 * GPR_BYTES)(r4) + lg r30,(GPRS_OFF + 17 * GPR_BYTES)(r4) + lg r31,(GPRS_OFF + 18 * GPR_BYTES)(r4) +#endif + + /* ??? Test r5 for pr_hasNoFloatUpdate and skip the fp load. + This is not yet set by the compiler. */ + + lfd f0,FPSCRS_OFF(r4) + + lfd f14,(FPRS_OFF + 0)(r4) + lfd f15,(FPRS_OFF + 8)(r4) + lfd f16,(FPRS_OFF + 16)(r4) + lfd f17,(FPRS_OFF + 24)(r4) + lfd f18,(FPRS_OFF + 32)(r4) + lfd f19,(FPRS_OFF + 40)(r4) + lfd f20,(FPRS_OFF + 48)(r4) + lfd f21,(FPRS_OFF + 56)(r4) + lfd f22,(FPRS_OFF + 64)(r4) + lfd f23,(FPRS_OFF + 72)(r4) + lfd f24,(FPRS_OFF + 80)(r4) + lfd f25,(FPRS_OFF + 88)(r4) + lfd f26,(FPRS_OFF + 96)(r4) + lfd f27,(FPRS_OFF + 104)(r4) + lfd f28,(FPRS_OFF + 112)(r4) + lfd f29,(FPRS_OFF + 120)(r4) + lfd f30,(FPRS_OFF + 128)(r4) + lfd f31,(FPRS_OFF + 136)(r4) + + mtfsf 0xff,f0 /* Restore fpscr. */ + + /* So now restore to entry of _ITM_beginTransaction. */ + lwz r0,CR_OFF(r4) + mtcr r0 /* Restore CR. */ + lg r0,PC_OFF(r4) + mtlr r0 /* Ret addr. */ + lg r1,SP_OFF(r4) /* SP. */ + blr + + /* End of GTM_longjump */ + /* End of sjlj.S */ + Index: libitm/config/darwin/powerpc/target.h =================================================================== --- libitm/config/darwin/powerpc/target.h (revision 0) +++ libitm/config/darwin/powerpc/target.h (revision 0) @@ -0,0 +1,78 @@ +/* Copyright (C) 2011 Free Software Foundation, Inc. + Contributed by Iain Sandoe . + Based on libitm/powerpc/target.h by Richard Henderson. + + This file is part of the GNU Transactional Memory Library (libitm). + + Libitm is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libitm is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +namespace GTM HIDDEN { + +/* We will assume that the code is to be built for a processor with Altivec. + If it is desired to make this run on Darwin 8 or earlier, which might be on + hardware with either G3 or G4, then the vecSave code in sjlj.S will need to + be made conditional on __cpu_has_altivec from the system framework (as is + done in Darwin's 'world_save ()' routine in libgcc). I.E. you need to check + for Altivec at runtime. */ + +typedef int v128 __attribute__((vector_size(16), may_alias, aligned(16))); + +typedef struct gtm_jmpbuf +{ + v128 vr[12]; /* vr20-vr31 */ +#ifndef __ppc64__ + unsigned int vecpad[2]; +#endif + void *ResForToc; + unsigned long pc; + double fpscr; + void *sp; + unsigned int cr; + unsigned int VRsave; + unsigned long gr[19]; /* r13-r31 */ + double fr[18]; /* f14-f31 */ +} gtm_jmpbuf; + +/* The size of one line in hardware caches (in bytes). */ +#ifdef __ppc64__ +# define HW_CACHELINE_SIZE 128 +#else +# define HW_CACHELINE_SIZE 64 +#endif + +static inline void +cpu_relax (void) +{ + __asm volatile ("" : : : "memory"); +} + +static inline void +atomic_read_barrier (void) +{ + __sync_synchronize (); +} + +static inline void +atomic_write_barrier (void) +{ + __sync_synchronize (); +} + +} // namespace GTM Index: libitm/configure.tgt =================================================================== --- libitm/configure.tgt (revision 181968) +++ libitm/configure.tgt (working copy) @@ -46,7 +46,8 @@ fi # Map the target cpu to an ARCH sub-directory. At the same time, # work out any special compilation flags as necessary. case "${target_cpu}" in - alpha*) ARCH=alpha ;; + alpha*) ARCH=alpha ;; + rs6000 | powerpc*) ARCH=powerpc ;; i[3456]86) case " ${CC} ${CFLAGS} " in @@ -90,6 +91,15 @@ case "${target}" in fi ;; + powerpc*-*-darwin*) + config_path="darwin/$ARCH $config_path" + ;; + + powerpc*-*-aix* | rs6000-*-aix*) + # The system ought to be supported, but sjlj.S has not been ported. + UNSUPPORTED=1 + ;; + *-*-gnu* | *-*-k*bsd*-gnu \ | *-*-netbsd* | *-*-freebsd* | *-*-openbsd* \ | *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11* \