X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Fdrc%2Femit_arm.c;h=91b474024e2ebe1cf0b7d1abfb6af427df272ee5;hb=2d2e57b2cf580eeea067c667183f8354d75b0238;hp=64face126d9742fcda472e645f06e311f4852672;hpb=f81107f59093904c3daac2e9c257261fddc6caf0;p=picodrive.git diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index 64face1..91b4740 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -6,6 +6,7 @@ * See COPYING file in the top-level directory. */ #define CONTEXT_REG 11 +#define RET_REG 0 // XXX: tcache_ptr type for SVP and SH2 compilers differs.. #define EMIT_PTR(ptr, x) \ @@ -243,6 +244,11 @@ #define EOP_MSR_IMM(ror2,imm) EOP_C_MSR_IMM(A_COND_AL,ror2,imm) #define EOP_MSR_REG(rm) EOP_C_MSR_REG(A_COND_AL,rm) +#define EOP_MOVW(rd,imm) \ + EMIT(0xe3000000 | ((rd)<<12) | ((imm)&0xfff) | (((imm)<<4)&0xf0000)) + +#define EOP_MOVT(rd,imm) \ + EMIT(0xe3400000 | ((rd)<<12) | (((imm)>>16)&0xfff) | (((imm)>>12)&0xf0000)) // XXX: AND, RSB, *C, will break if 1 insn is not enough static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int imm) @@ -257,6 +263,19 @@ static void emith_op_imm2(int cond, int s, int op, int rd, int rn, unsigned int imm = ~imm; op = A_OP_MVN; } +#ifdef HAVE_ARMV7 + for (v = imm, ror2 = 0; v && !(v & 3); v >>= 2) + ror2--; + if (v >> 8) { + /* 2+ insns needed - prefer movw/movt */ + if (op == A_OP_MVN) + imm = ~imm; + EOP_MOVW(rd, imm); + if (imm & 0xffff0000) + EOP_MOVT(rd, imm); + return; + } +#endif break; case A_OP_EOR: @@ -351,6 +370,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define EMITH_NOTHING1(cond) \ (void)(cond) +#define EMITH_SJMP_DECL_() +#define EMITH_SJMP_START_(cond) EMITH_NOTHING1(cond) +#define EMITH_SJMP_END_(cond) EMITH_NOTHING1(cond) #define EMITH_SJMP_START(cond) EMITH_NOTHING1(cond) #define EMITH_SJMP_END(cond) EMITH_NOTHING1(cond) #define EMITH_SJMP3_START(cond) EMITH_NOTHING1(cond) @@ -360,6 +382,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_move_r_r(d, s) \ EOP_MOV_REG_SIMPLE(d, s) +#define emith_move_r_r_ptr(d, s) \ + emith_move_r_r(d, s) + #define emith_mvn_r_r(d, s) \ EOP_MVN_REG(A_COND_AL,0,d,s,A_AM1_LSL,0) @@ -411,6 +436,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_tst_r_r(d, s) \ EOP_TST_REG(A_COND_AL,d,s,A_AM1_LSL,0) +#define emith_tst_r_r_ptr(d, s) \ + emith_tst_r_r(d, s) + #define emith_teq_r_r(d, s) \ EOP_TEQ_REG(A_COND_AL,d,s,A_AM1_LSL,0) @@ -503,6 +531,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_add_r_r_imm(d, s, imm) \ emith_op_imm2(A_COND_AL, 0, A_OP_ADD, d, s, imm) +#define emith_add_r_r_ptr_imm(d, s, imm) \ + emith_add_r_r_imm(d, s, imm) + #define emith_sub_r_r_imm(d, s, imm) \ emith_op_imm2(A_COND_AL, 0, A_OP_SUB, d, s, imm) @@ -593,6 +624,9 @@ static int emith_xbranch(int cond, void *target, int is_call) #define emith_ctx_read(r, offs) \ emith_read_r_r_offs(r, CONTEXT_REG, offs) +#define emith_ctx_read_ptr(r, offs) \ + emith_ctx_read(r, offs) + #define emith_ctx_write(r, offs) \ EOP_STR_IMM(r, CONTEXT_REG, offs)