diff --git a/src/Makefile b/src/Makefile index 5c3e6a89..7976d419 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,6 +52,7 @@ CCOPT= -O2 -fomit-frame-pointer CCOPT_X86= -march=i686 CCOPT_X64= CCOPT_ARM= +CCOPT_PPC= CCOPT_PPCSPE= # CCDEBUG= @@ -228,6 +229,10 @@ ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH))) TARGET_CCARCH= arm TARGET_XCFLAGS+= $(CCOPT_ARM) else +ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH))) + TARGET_CCARCH= ppc + TARGET_XCFLAGS+= $(CCOPT_PPC) +else ifneq (,$(findstring LJ_TARGET_PPCSPE ,$(TARGET_TESTARCH))) TARGET_CCARCH= ppcspe TARGET_XCFLAGS+= $(CCOPT_PPCSPE) @@ -237,6 +242,7 @@ endif endif endif endif +endif ifneq (,$(PREFIX)) ifneq (/usr/local,$(PREFIX)) @@ -341,6 +347,7 @@ DASM_FLAGS_X86= DASM_FLAGS_X64= -D X64 DASM_FLAGS_X64WIN= -D X64 -D X64WIN DASM_FLAGS_ARM= +DASM_FLAGS_PPC= DASM_FLAGS_PPCSPE= BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o @@ -387,7 +394,7 @@ ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T) ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP) ALL_DYNGEN= buildvm_x86.h buildvm_x64.h buildvm_x64win.h buildvm_arm.h \ - buildvm_ppcspe.h + buildvm_ppc.h buildvm_ppcspe.h WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM) @@ -478,6 +485,7 @@ distclean: clean $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_X64) -o buildvm_x64.h buildvm_x86.dasc $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_X64WIN) -o buildvm_x64win.h buildvm_x86.dasc $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_ARM) -o buildvm_arm.h buildvm_arm.dasc + $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPC) -o buildvm_ppc.h buildvm_ppc.dasc $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPCSPE) -o buildvm_ppcspe.h buildvm_ppcspe.dasc depend: @@ -516,6 +524,10 @@ buildvm_arm.h: buildvm_arm.dasc $(E) "DYNASM $@" $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_ARM) -o $@ buildvm_arm.dasc +buildvm_ppc.h: buildvm_ppc.dasc + $(E) "DYNASM $@" + $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_PPC) -o $@ buildvm_ppc.dasc + buildvm_ppcspe.h: buildvm_ppcspe.dasc $(E) "DYNASM $@" $(Q)$(DASM) $(DASM_FLAGS) $(DASM_FLAGS_PPCSPE) -o $@ buildvm_ppcspe.dasc diff --git a/src/buildvm.c b/src/buildvm.c index 33f87a4b..122e1262 100644 --- a/src/buildvm.c +++ b/src/buildvm.c @@ -67,6 +67,9 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type); #elif LJ_TARGET_ARM #include "../dynasm/dasm_arm.h" #include "buildvm_arm.h" +#elif LJ_TARGET_PPC +#include "../dynasm/dasm_ppc.h" +#include "buildvm_ppc.h" #elif LJ_TARGET_PPCSPE #include "../dynasm/dasm_ppc.h" #include "buildvm_ppcspe.h" diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index 4e316883..2964e0e2 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc @@ -10,10 +10,6 @@ |.globalnames globnames |.externnames extnames | -|.if not SPE -|.error "No support for plain PowerPC CPUs (yet)" -|.endif -| |// Note: The ragged indentation of the instructions is intentional. |// The starting columns indicate data dependencies. | @@ -32,14 +28,12 @@ | |// Constants for vectorized type-comparisons (hi+low GPR). C callee-save. |.define TISNUM, r22 -|.if SPE -|.define TISSTR, r23 -|.define TISTAB, r24 -|.define TISFUNC, r25 -|.define TISNIL, r26 -|.define TOBIT, r27 -|.define ZERO, TOBIT // Zero in lo word. -|.endif +|.define TISNIL, r23 +|.define ZERO, r24 +|.define TISSTR, r25 // NYI: remove. +|.define TISTAB, r26 // NYI: remove. +|.define TISFUNC, r27 // NYI: remove. +|.define TOBIT, r28 // NYI: use FP reg. | |// The following temporaries are not saved across C calls, except for RA. |.define RA, r20 // Callee-save. @@ -63,32 +57,19 @@ |.define CARG4, r6 // Overlaps TMP3. |.define CARG5, r7 // Overlaps INS. | +|.define CARGF1, f1 +|.define CARGF2, f2 +| |.define CRET1, r3 |.define CRET2, r4 | |// Stack layout while in interpreter. Must match with lj_frame.h. -|.if SPE -|.define SAVE_LR, 180(sp) -|.define CFRAME_SPACE, 176 // Delta for sp. -|// Back chain for sp: 176(sp) <-- sp entering interpreter -|.define SAVE_r31, 168(sp) // 64 bit register saves. -|.define SAVE_r30, 160(sp) -|.define SAVE_r29, 152(sp) -|.define SAVE_r28, 144(sp) -|.define SAVE_r27, 136(sp) -|.define SAVE_r26, 128(sp) -|.define SAVE_r25, 120(sp) -|.define SAVE_r24, 112(sp) -|.define SAVE_r23, 104(sp) -|.define SAVE_r22, 96(sp) -|.define SAVE_r21, 88(sp) -|.define SAVE_r20, 80(sp) -|.define SAVE_r19, 72(sp) -|.define SAVE_r18, 64(sp) -|.define SAVE_r17, 56(sp) -|.define SAVE_r16, 48(sp) -|.define SAVE_r15, 40(sp) -|.define SAVE_r14, 32(sp) +|.define SAVE_LR, 260(sp) +|.define CFRAME_SPACE, 256 // Delta for sp. +|// Back chain for sp: 256(sp) <-- sp entering interpreter +|.define SAVE_GPR_, 184 // .. 184+18*4: 32 bit GPR saves. +|.define SAVE_FPR_, 40 // .. 40+18*8: 64 bit FPR saves. +|.define SAVE_UNUSED, 32(sp) // 8 unused bytes for alignment. |.define SAVE_ERRF, 28(sp) // 32 bit C frame info. |.define SAVE_NRES, 24(sp) |.define SAVE_CFRAME, 20(sp) @@ -98,25 +79,30 @@ |// Next frame lr: 4(sp) |// Back chain for sp: 0(sp) <-- sp while in interpreter | -|.macro save_, reg; evstdd reg, SAVE_..reg; .endmacro -|.macro rest_, reg; evldd reg, SAVE_..reg; .endmacro -|.endif +|.macro save_, reg +| stw r..reg, SAVE_GPR_+(reg-14)*4(sp) +| stfd f..reg, SAVE_FPR_+(reg-14)*8(sp) +|.endmacro +|.macro rest_, reg +| lwz r..reg, SAVE_GPR_+(reg-14)*4(sp) +| lfd f..reg, SAVE_FPR_+(reg-14)*8(sp) +|.endmacro | |.macro saveregs | stwu sp, -CFRAME_SPACE(sp) -| save_ r14; save_ r15; save_ r16; save_ r17; save_ r18; save_ r19 +| save_ 14; save_ 15; save_ 16; save_ 17; save_ 18; save_ 19 | mflr r0 -| save_ r20; save_ r21; save_ r22; save_ r23; save_ r24; save_ r25 +| save_ 20; save_ 21; save_ 22; save_ 23; save_ 24; save_ 25 | stw r0, SAVE_LR -| save_ r26; save_ r27; save_ r28; save_ r29; save_ r30; save_ r31 +| save_ 26; save_ 27; save_ 28; save_ 29; save_ 30; save_ 31 |.endmacro | |.macro restoreregs | lwz r0, SAVE_LR -| rest_ r14; rest_ r15; rest_ r16; rest_ r17; rest_ r18; rest_ r19 +| rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19 | mtlr r0 -| rest_ r20; rest_ r21; rest_ r22; rest_ r23; rest_ r24; rest_ r25 -| rest_ r26; rest_ r27; rest_ r28; rest_ r29; rest_ r30; rest_ r31 +| rest_ 20; rest_ 21; rest_ 22; rest_ 23; rest_ 24; rest_ 25 +| rest_ 26; rest_ 27; rest_ 28; rest_ 29; rest_ 30; rest_ 31 | addi sp, sp, CFRAME_SPACE |.endmacro | @@ -231,17 +217,15 @@ |//----------------------------------------------------------------------- | |// Macros to test operand types. -|.if SPE -|.macro checknum, reg; evcmpltu reg, TISNUM; .endmacro -|.macro checkstr, reg; evcmpeq reg, TISSTR; .endmacro -|.macro checktab, reg; evcmpeq reg, TISTAB; .endmacro -|.macro checkfunc, reg; evcmpeq reg, TISFUNC; .endmacro -|.macro checknil, reg; evcmpeq reg, TISNIL; .endmacro -|.macro checkok, label; blt label; .endmacro -|.macro checkfail, label; bge label; .endmacro -|.macro checkanyfail, label; bns label; .endmacro -|.macro checkallok, label; bso label; .endmacro -|.endif +|.macro checknum, reg; cmplw reg, TISNUM; .endmacro +|.macro checkstr, reg; cmpwi reg, LJ_TSTR; .endmacro +|.macro checktab, reg; cmpwi reg, LJ_TTAB; .endmacro +|.macro checkfunc, reg; cmpwi reg, LJ_TFUNC; .endmacro +|.macro checknil, reg; cmpwi reg, LJ_TNIL; .endmacro +|.macro checkok, label; beq label; .endmacro // NYI: remove. +|.macro checkfail, label; bne label; .endmacro // NYI: remove. +|.macro checkanyfail, label; bns label; .endmacro // NYI: remove. +|.macro checkallok, label; bso label; .endmacro // NYI: remove. | |.macro branch_RD | srwi TMP0, RD, 1 @@ -1067,11 +1051,7 @@ static void build_subroutines(BuildCtx *ctx) | checknum CARG1 | cmplwi cr1, TMP0, 0 | stw BASE, L->base // Add frame since C call can throw. - |.if SPE - | crand 4*cr0+eq, 4*cr0+lt, 4*cr1+eq - |.else - |.error "NYI" - |.endif + | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq | stw PC, SAVE_PC // Redundant (but a defined value). | bne ->fff_fallback | ffgccheck @@ -3672,14 +3652,10 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", (int)ctx->codesz, CFRAME_SIZE); for (i = 14; i <= 31; i++) -#if LJ_TARGET_PPCSPE fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n" - "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", - 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); -#else -#error "missing frame info for saved registers" -#endif + "\t.byte %d\n\t.uleb128 %d\n", + 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i)); fprintf(ctx->fp, "\t.align 2\n" ".LEFDE0:\n\n"); @@ -3713,14 +3689,10 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", (int)ctx->codesz, CFRAME_SIZE); for (i = 14; i <= 31; i++) -#if LJ_TARGET_PPCSPE fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n" - "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", - 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); -#else -#error "missing frame info for saved registers" -#endif + "\t.byte %d\n\t.uleb128 %d\n", + 0x80+i, 37+(31-i), 0x80+32+i, 2+2*(31-i)); fprintf(ctx->fp, "\t.align 2\n" ".LEFDE1:\n\n"); diff --git a/src/buildvm_ppc.h b/src/buildvm_ppc.h new file mode 100644 index 00000000..0a33c11c --- /dev/null +++ b/src/buildvm_ppc.h @@ -0,0 +1 @@ +/* Placeholder file. */ diff --git a/src/lj_arch.h b/src/lj_arch.h index fff40838..17b766f8 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -147,6 +147,20 @@ #elif LUAJIT_TARGET == LUAJIT_ARCH_PPC +#define LJ_ARCH_NAME "ppc" +#define LJ_ARCH_BITS 32 +#define LJ_ARCH_ENDIAN LUAJIT_BE +#define LJ_ARCH_HASFPU 1 +#define LJ_TARGET_PPC 1 +#define LJ_TARGET_EHRETREG 3 +#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */ +#define LJ_TARGET_MASKSHIFT 0 +#define LJ_TARGET_MASKROT 1 +#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */ +#define LJ_ARCH_DUALNUM 1 +#define LJ_ARCH_NOFFI 1 /* NYI: comparisons, calls. */ +#define LJ_ARCH_NOJIT 1 + #error "No support for plain PowerPC CPUs (yet)" #elif LUAJIT_TARGET == LUAJIT_ARCH_PPCSPE diff --git a/src/lj_frame.h b/src/lj_frame.h index 4a2a767a..f09b73d0 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h @@ -67,7 +67,6 @@ enum { #define CFRAME_OFS_PC (6*4) #define CFRAME_OFS_MULTRES (5*4) #define CFRAME_SIZE (12*4) -#define CFRAME_SIZE_JIT CFRAME_SIZE #define CFRAME_SHIFT_MULTRES 0 #elif LJ_TARGET_X64 #if LJ_ABI_WIN @@ -99,7 +98,15 @@ enum { #define CFRAME_OFS_PC 8 #define CFRAME_OFS_MULTRES 4 #define CFRAME_SIZE 64 -#define CFRAME_SIZE_JIT CFRAME_SIZE +#define CFRAME_SHIFT_MULTRES 3 +#elif LJ_TARGET_PPC +#define CFRAME_OFS_ERRF 28 +#define CFRAME_OFS_NRES 24 +#define CFRAME_OFS_PREV 20 +#define CFRAME_OFS_L 16 +#define CFRAME_OFS_PC 12 +#define CFRAME_OFS_MULTRES 8 +#define CFRAME_SIZE 256 #define CFRAME_SHIFT_MULTRES 3 #elif LJ_TARGET_PPCSPE #define CFRAME_OFS_ERRF 28 @@ -109,12 +116,15 @@ enum { #define CFRAME_OFS_PC 12 #define CFRAME_OFS_MULTRES 8 #define CFRAME_SIZE 176 -#define CFRAME_SIZE_JIT CFRAME_SIZE #define CFRAME_SHIFT_MULTRES 3 #else #error "Missing CFRAME_* definitions for this architecture" #endif +#ifndef CFRAME_SIZE_JIT +#define CFRAME_SIZE_JIT CFRAME_SIZE +#endif + #define CFRAME_RESUME 1 #define CFRAME_UNWIND_FF 2 /* Only used in unwinder. */ #define CFRAME_RAWMASK (~(intptr_t)(CFRAME_RESUME|CFRAME_UNWIND_FF))