X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=Pico%2Fcarthw%2Fsvp%2Fgen_arm.c;h=87e8368045f91cbf44dc253d6d55fae7c4d5f679;hb=0e4d7ba5f42c0649d9dcc905d29b04d5a11ecd9c;hp=56be5623c6a674888b5167c93e86cb47b3f44814;hpb=d274c33b6b4607f0bf2361610a1e53fd1dd04195;p=picodrive.git diff --git a/Pico/carthw/svp/gen_arm.c b/Pico/carthw/svp/gen_arm.c index 56be562..87e8368 100644 --- a/Pico/carthw/svp/gen_arm.c +++ b/Pico/carthw/svp/gen_arm.c @@ -12,6 +12,9 @@ #define A_COND_AL 0xe #define A_COND_EQ 0x0 +#define A_COND_NE 0x1 +#define A_COND_MI 0x4 +#define A_COND_PL 0x5 /* addressing mode 1 */ #define A_AM1_LSL 0 @@ -21,12 +24,16 @@ #define A_AM1_IMM(ror2,imm8) (((ror2)<<8) | (imm8) | 0x02000000) #define A_AM1_REG_XIMM(shift_imm,shift_op,rm) (((shift_imm)<<7) | ((shift_op)<<5) | (rm)) +#define A_AM1_REG_XREG(rs,shift_op,rm) (((rs)<<8) | ((shift_op)<<5) | 0x10 | (rm)) /* data processing op */ #define A_OP_AND 0x0 +#define A_OP_EOR 0x1 #define A_OP_SUB 0x2 +#define A_OP_RSB 0x3 #define A_OP_ADD 0x4 #define A_OP_TST 0x8 +#define A_OP_CMP 0xa #define A_OP_ORR 0xc #define A_OP_MOV 0xd #define A_OP_BIC 0xe @@ -34,8 +41,9 @@ #define EOP_C_DOP_X(cond,op,s,rn,rd,shifter_op) \ EMIT(((cond)<<28) | ((op)<< 21) | ((s)<<20) | ((rn)<<16) | ((rd)<<12) | (shifter_op)) -#define EOP_C_DOP_IMM(cond,op,s,rn,rd,ror2,imm8) EOP_C_DOP_X(cond,op,s,rn,rd,A_AM1_IMM(ror2,imm8)) -#define EOP_C_DOP_REG(cond,op,s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_X(cond,op,s,rn,rd,A_AM1_REG_XIMM(shift_imm,shift_op,rm)) +#define EOP_C_DOP_IMM( cond,op,s,rn,rd,ror2,imm8) EOP_C_DOP_X(cond,op,s,rn,rd,A_AM1_IMM(ror2,imm8)) +#define EOP_C_DOP_REG_XIMM(cond,op,s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_X(cond,op,s,rn,rd,A_AM1_REG_XIMM(shift_imm,shift_op,rm)) +#define EOP_C_DOP_REG_XREG(cond,op,s,rn,rd,rs, shift_op,rm) EOP_C_DOP_X(cond,op,s,rn,rd,A_AM1_REG_XREG(rs, shift_op,rm)) #define EOP_MOV_IMM(rd, ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_MOV,0, 0,rd,ror2,imm8) #define EOP_ORR_IMM(rd,rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_ORR,0,rn,rd,ror2,imm8) @@ -43,11 +51,17 @@ #define EOP_BIC_IMM(rd,rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_BIC,0,rn,rd,ror2,imm8) #define EOP_AND_IMM(rd,rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_AND,0,rn,rd,ror2,imm8) #define EOP_SUB_IMM(rd,rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_SUB,0,rn,rd,ror2,imm8) +#define EOP_TST_IMM( rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_TST,1,rn, 0,ror2,imm8) +#define EOP_RSB_IMM(rd,rn,ror2,imm8) EOP_C_DOP_IMM(A_COND_AL,A_OP_RSB,0,rn,rd,ror2,imm8) -#define EOP_MOV_REG(s, rd,shift_imm,shift_op,rm) EOP_C_DOP_REG(A_COND_AL,A_OP_MOV,s, 0,rd,shift_imm,shift_op,rm) -#define EOP_ORR_REG(s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_REG(A_COND_AL,A_OP_ORR,s,rn,rd,shift_imm,shift_op,rm) -#define EOP_ADD_REG(s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_REG(A_COND_AL,A_OP_ADD,s,rn,rd,shift_imm,shift_op,rm) -#define EOP_TST_REG( rn, shift_imm,shift_op,rm) EOP_C_DOP_REG(A_COND_AL,A_OP_TST,1,rn, 0,shift_imm,shift_op,rm) +#define EOP_MOV_REG(s, rd,shift_imm,shift_op,rm) EOP_C_DOP_REG_XIMM(A_COND_AL,A_OP_MOV,s, 0,rd,shift_imm,shift_op,rm) +#define EOP_ORR_REG(s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_REG_XIMM(A_COND_AL,A_OP_ORR,s,rn,rd,shift_imm,shift_op,rm) +#define EOP_ADD_REG(s,rn,rd,shift_imm,shift_op,rm) EOP_C_DOP_REG_XIMM(A_COND_AL,A_OP_ADD,s,rn,rd,shift_imm,shift_op,rm) +#define EOP_TST_REG( rn, shift_imm,shift_op,rm) EOP_C_DOP_REG_XIMM(A_COND_AL,A_OP_TST,1,rn, 0,shift_imm,shift_op,rm) + +#define EOP_MOV_REG2(s, rd,rs,shift_op,rm) EOP_C_DOP_REG_XREG(A_COND_AL,A_OP_MOV,s, 0,rd,rs,shift_op,rm) +#define EOP_ADD_REG2(s,rn,rd,rs,shift_op,rm) EOP_C_DOP_REG_XREG(A_COND_AL,A_OP_ADD,s,rn,rd,rs,shift_op,rm) +#define EOP_SUB_REG2(s,rn,rd,rs,shift_op,rm) EOP_C_DOP_REG_XREG(A_COND_AL,A_OP_SUB,s,rn,rd,rs,shift_op,rm) #define EOP_MOV_REG_SIMPLE(rd,rm) EOP_MOV_REG(0,rd,0,A_AM1_LSL,rm) #define EOP_MOV_REG_LSL(rd, rm,shift_imm) EOP_MOV_REG(0,rd,shift_imm,A_AM1_LSL,rm) @@ -67,6 +81,11 @@ #define EOP_TST_REG_SIMPLE(rn,rm) EOP_TST_REG( rn, 0,A_AM1_LSL,rm) +#define EOP_MOV_REG2_LSL(rd, rm,rs) EOP_MOV_REG2(0, rd,rs,A_AM1_LSL,rm) +#define EOP_MOV_REG2_ROR(rd, rm,rs) EOP_MOV_REG2(0, rd,rs,A_AM1_ROR,rm) +#define EOP_ADD_REG2_LSL(rd,rn,rm,rs) EOP_ADD_REG2(0,rn,rd,rs,A_AM1_LSL,rm) +#define EOP_SUB_REG2_LSL(rd,rn,rm,rs) EOP_SUB_REG2(0,rn,rd,rs,A_AM1_LSL,rm) + /* addressing mode 2 */ #define EOP_C_AM2_IMM(cond,u,b,l,rn,rd,offset_12) \ EMIT(((cond)<<28) | 0x05000000 | ((u)<<23) | ((b)<<22) | ((l)<<20) | ((rn)<<16) | ((rd)<<12) | (offset_12)) @@ -113,24 +132,37 @@ #define EOP_MUL(rd,rm,rs) EOP_C_MUL(A_COND_AL,0,rd,rs,rm) // note: rd != rm +#define EOP_C_MRS(cond,rd) \ + EMIT(((cond)<<28) | 0x010f0000 | ((rd)<<12)) + +#define EOP_C_MSR_IMM(cond,ror2,imm) \ + EMIT(((cond)<<28) | 0x0328f000 | ((ror2)<<8) | (imm)) // cpsr_f + +#define EOP_C_MSR_REG(cond,rm) \ + EMIT(((cond)<<28) | 0x0128f000 | (rm)) // cpsr_f + +#define EOP_MRS(rd) EOP_C_MRS(A_COND_AL,rd) +#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) + -static void emit_mov_const(int d, unsigned int val) +static void emit_mov_const(int cond, int d, unsigned int val) { int need_or = 0; if (val & 0xff000000) { - EOP_MOV_IMM(d, 8/2, (val>>24)&0xff); + EOP_C_DOP_IMM(cond, A_OP_MOV, 0, 0, d, 8/2, (val>>24)&0xff); need_or = 1; } if (val & 0x00ff0000) { - EOP_C_DOP_IMM(A_COND_AL,need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 16/2, (val>>16)&0xff); + EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 16/2, (val>>16)&0xff); need_or = 1; } if (val & 0x0000ff00) { - EOP_C_DOP_IMM(A_COND_AL,need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 24/2, (val>>8)&0xff); + EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 24/2, (val>>8)&0xff); need_or = 1; } if ((val &0x000000ff) || !need_or) - EOP_C_DOP_IMM(A_COND_AL,need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff); + EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff); } /* @@ -176,7 +208,7 @@ static void emit_block_epilogue(int icount) static void emit_pc_dump(int pc) { - emit_mov_const(3, pc<<16); + emit_mov_const(A_COND_AL, 3, pc<<16); EOP_STR_IMM(3,7,0x400+6*4); // str r3, [r7, #(0x400+6*8)] }