* |rotimm | immed_8 |
* +-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define arm_so_imm(rot,imm) (((rot)<<8)|(imm))
+#define arm_so_i(rot,imm) ((((rot)&15)<<8)|((imm)&255))
/* 1
* 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+
* | Si | St |0| Rm |
* +-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define arm_so_shift_imm(Si,St,Rm) (((Si)<<7)|((St)<<5)|(Rm))
-#define arm_so_rrx_reg(Rm) arm_so_shift_imm(0,ORC_ARM_ROR,Rm)
-#define arm_so_reg(Rm) (Rm)
+#define arm_so_rsi(Si,St,Rm) ((((Si)&31)<<7)|(((St)&7)<<5)|((Rm)&7))
+#define arm_so_rrx(Rm) arm_so_rsi(0,ORC_ARM_ROR,Rm)
+#define arm_so_r(Rm) ((Rm)&7)
/* 1
* 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+
* | Rs |0| St |1| Rm |
* +-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define arm_so_shift_reg(Rs,St,Rm) (0x008|((Rs)<<8)|((St)<<5)|(Rm))
+#define arm_so_rsr(Rs,St,Rm) (0x008|(((Rs)&15)<<8)|(((St)&7)<<5)|((Rm)&7))
/* data processing instructions */
/* 3 2 2 2 2 2 2 2 1 1 1 1 1
* | cond |0 0|I| opcode|S| Rn | Rd | shifter_operand |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define arm_dp(cond,I,opcode,S,Rn,Rd,So) (((cond)<<28)|((I)<<25)|((opcode)<<21)|((S)<<20)|((Rn)<<16)|((Rd)<<12)|So)
-#define arm_dp_reg(cond,opcode,S,Rn,Rd,So) arm_dp (cond,0,opcode,S,Rn,Rd,So)
-#define arm_dp_imm(cond,opcode,S,Rn,Rd,So) arm_dp (cond,1,opcode,S,Rn,Rd,So)
+#define arm_code_dp(cond,I,opcode,S,Rn,Rd,So) ((((cond)&15)<<28) | (((I)&1)<<25) | \
+ (((opcode)&15)<<21) | (((S)&1)<<20) | \
+ (((Rn)&15)<<16) | (((Rd)&15)<<12) | \
+ ((So)&0xfff))
/*
* type 0: <op>{<cond>}{s} {<Rd>}, <Rn>, #imm (imm = (val>>(shift*2))|(val<<(32-(shift*2))))
*/
void
orc_arm_emit_dp (OrcCompiler *p, int type, OrcArmCond cond, OrcArmDP opcode,
- int S, int Rd, int Rn, int Rm, int shift, int val)
+ int S, int Rd, int Rn, int Rm, int shift, uint32_t val)
{
uint32_t code;
int I = 0;
int shifter_op;
- char shifter[100];
+ char shifter[64];
uint32_t imm;
static const char *shift_names[] = {
"LSL", "LSR", "ASR", "ROR"
switch (type) {
case 0:
/* #imm */
- imm = val & 0xff;
- shifter_op = arm_so_imm (shift, imm);
- if (shift > 0)
- imm = (imm >> (shift*2)) | (imm << (32-(shift*2)));
- snprintf (shifter, sizeof(shifter), "#%08x", imm);
+ imm = (uint32_t) val;
+ /* if imm <= 0xff we're done. It's recommanded that we choose the
+ * smallest shifter value. Impossible values will overflow the shifter. */
+ while (imm > 0xff && shift < 16) {
+ imm = (imm << 2) | (imm >> 30);
+ shift++;
+ }
+ if (shift > 15) {
+ ORC_COMPILER_ERROR(p,"invalid ARM immediate %08x", val);
+ return;
+ }
+ shifter_op = arm_so_i (shift, imm);
+ snprintf (shifter, sizeof(shifter), "#%08x", val);
I = 1;
break;
case 1:
/* <Rm> */
- shifter_op = arm_so_reg (Rm);
+ shifter_op = arm_so_r (Rm);
snprintf (shifter, sizeof(shifter), "%s", orc_arm_reg_name (Rm));
break;
case 2:
/* <Rm>, [LSL|LSR|ASR] #imm */
- shifter_op = arm_so_shift_imm (val,shift,Rm);
+ shifter_op = arm_so_rsi (val,shift,Rm);
snprintf (shifter, sizeof(shifter), "%s, %s #%d",
orc_arm_reg_name (Rm), shift_names[shift], val);
break;
case 3:
/* <Rm>, [LSL|LSR|ASR] <Rs> */
- shifter_op = arm_so_shift_reg (val,shift,Rm);
+ shifter_op = arm_so_rsr (val,shift,Rm);
snprintf (shifter, sizeof(shifter), "%s, %s %s",
orc_arm_reg_name (Rm), shift_names[shift], orc_arm_reg_name (val));
break;
case 4:
/* <Rm>, RRX */
- shifter_op = arm_so_rrx_reg (Rm);
+ shifter_op = arm_so_rrx (Rm);
snprintf (shifter, sizeof(shifter), "%s, RRX",
orc_arm_reg_name (Rm));
break;
if (op_Rd[opcode]) {
if (op_Rn[opcode]) {
/* opcode using Rn */
- code = arm_dp (cond, I, opcode, S, Rn, Rd, shifter_op);
+ code = arm_code_dp (cond, I, opcode, S, Rn, Rd, shifter_op);
ORC_ASM_CODE(p," %s%s%s %s, %s, %s\n",
dp_insn_names[opcode], orc_arm_cond_name(cond), (S ? "s" : ""),
orc_arm_reg_name (Rd), orc_arm_reg_name (Rn), shifter);
} else {
/* opcode using Rd and val (mov, mvn) */
- code = arm_dp (cond, I, opcode, S, Rn, Rd, shifter_op);
+ code = arm_code_dp (cond, I, opcode, S, Rn, Rd, shifter_op);
ORC_ASM_CODE(p," %s%s%s %s, %s\n",
dp_insn_names[opcode], orc_arm_cond_name(cond), (S ? "s" : ""),
orc_arm_reg_name (Rd), shifter);
}
} else {
/* opcode does not change Rd, change status register (cmp, tst, ..) */
- code = arm_dp (cond, I, opcode, 1, Rn, 0, shifter_op);
+ code = arm_code_dp (cond, I, opcode, 1, Rn, 0, shifter_op);
ORC_ASM_CODE(p," %s%s %s, %s\n",
dp_insn_names[opcode], orc_arm_cond_name(cond), orc_arm_reg_name (Rn), shifter);
}
* | cond | mode | Rn | Rd |0 0 0 0| op | Rm |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define arm_code_mm(cond,mode,Rn,Rd,op,Rm) (((cond)<<28)|((mode)<<20)|((Rn)<<16)|((Rd)<<12)|((op)<<4)|(Rm))
+#define arm_code_par(cond,mode,Rn,Rd,op,Rm) (((cond)<<28)|((mode)<<20)|((Rn)<<16)|((Rd)<<12)|((op)<<4)|(Rm))
void
-orc_arm_emit_mm (OrcCompiler *p, const char *name, OrcArmCond cond, int mode,
- int op, int dest, int src1, int src2)
+orc_arm_emit_par (OrcCompiler *p, int op, int mode, OrcArmCond cond,
+ int Rd, int Rn, int Rm)
{
uint32_t code;
+ static const int par_op[] = {
+ 1, 3, 5, 7, 9, 15, 11, 5, 5
+ };
+ static const char *par_op_names[] = {
+ "add16", "addsubx", "subaddx", "sub16", "add8", "sub8", "sel", "add", "sub"
+ };
+ static const int par_mode[] = {
+ 0x61, 0x62, 0x63, 0x65, 0x66, 0x67, 0x68, 0x10, 0x12, 0x14, 0x16
+ };
+ static const char *par_mode_names[] = {
+ "s", "q", "sh", "u", "uq", "uh", "", "q", "q", "qd", "qd"
+ };
- code = arm_code_mm (cond, mode, src1, dest, op, src2);
- ORC_ASM_CODE(p," %s%s %s, %s, %s\n",
- name, orc_arm_cond_name(cond),
- orc_arm_reg_name (dest),
- orc_arm_reg_name (src1),
- orc_arm_reg_name (src2));
+ code = arm_code_par (cond, par_mode[mode], Rn, Rd, par_op[op], Rm);
+ ORC_ASM_CODE(p," %s%s%s %s, %s, %s\n",
+ par_mode_names[mode], par_op_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd),
+ orc_arm_reg_name (Rn),
+ orc_arm_reg_name (Rm));
+ orc_arm_emit (p, code);
+}
+
+/* extend instructions */
+/* 3 2 2 2 2 2 2 2 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | cond |0 1 1 0 0 0 0 0| Rn | Rd |rot|0 0|0 1 1 1| Rm |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+#define arm_code_xt(op,cond,Rn,Rd,r8,Rm) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|(((r8)&0x18)<<7)|(Rm))
+
+void
+orc_arm_emit_xt (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rn, int Rm, int r8)
+{
+ uint32_t code;
+ char shifter[64];
+ static const uint32_t xt_opcodes[] = {
+ 0x06800070, 0x06a00070, 0x06b00070, 0x06c00070, 0x06e00070, 0x06f00070
+ };
+ static const char *xt_insn_names[] = {
+ "sxtb16", "sxtb", "sxth", "uxtb16", "uxtb", "uxth",
+ "sxtab16", "sxtab", "sxtah", "uxtab16", "uxtab", "uxtah",
+ };
+
+ if (r8 & 0x18)
+ snprintf (shifter, sizeof (shifter), ", ROR #%d", r8 & 0x18);
+ else
+ shifter[0] = '\0';
+
+ code = arm_code_xt (xt_opcodes[op], cond, Rn, Rd, r8, Rm);
+ if (Rn < 15) {
+ /* with Rn */
+ ORC_ASM_CODE(p," %s%s %s, %s, %s%s\n",
+ xt_insn_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd),
+ orc_arm_reg_name (Rn),
+ orc_arm_reg_name (Rm),
+ shifter);
+ } else {
+ ORC_ASM_CODE(p," %s%s %s, %s%s\n",
+ xt_insn_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd),
+ orc_arm_reg_name (Rm),
+ shifter);
+ }
+ orc_arm_emit (p, code);
+}
+
+#define arm_code_pkh(op,cond,Rn,Rd,sh,Rm) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|((sh)<<7)|(Rm))
+void
+orc_arm_emit_pkh (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rn, int Rm, int sh)
+{
+ uint32_t code;
+ char shifter[64];
+ static const uint32_t pkh_opcodes[] = { 0x06800010, 0x06800050 };
+ static const char *pkh_insn_names[] = { "pkhbt", "pkhtb" };
+
+ if (sh > 0) {
+ snprintf (shifter, sizeof (shifter), ", %s #%d",
+ (op == 0 ? "LSL" : "ASR"), sh);
+ } else {
+ shifter[0] = '\0';
+ }
+
+ code = arm_code_pkh (pkh_opcodes[op], cond, Rn, Rd, sh, Rm);
+ ORC_ASM_CODE(p," %s%s %s, %s, %s%s\n",
+ pkh_insn_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd),
+ orc_arm_reg_name (Rn),
+ orc_arm_reg_name (Rm),
+ shifter);
+ orc_arm_emit (p, code);
+}
+
+/* extend instructions */
+/* 3 2 2 2 2 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | cond |0 1 1 0|x x x| sat | Rd | sh |a|0 1| Rm |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+#define arm_code_sat(op,cond,sat,Rd,sh,a,Rm) (op|(((cond)&15)<<28)|(((sat)&31)<<16)|\
+ (((Rd)&15)<<12)|(((sh)&31)<<7)|(((a)&1)<<6)|\
+ ((Rm)&15))
+void
+orc_arm_emit_sat (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int sat, int Rm, int sh, int asr)
+{
+ uint32_t code;
+ char shifter[64];
+ static const uint32_t sat_opcodes[] = { 0x06a00010, 0x06e00010, 0, 0 };
+ static const char *sat_insn_names[] = { "ssat", "usat", "ssat16", "usat16" };
+ static const int par_mode[] = { 0, 0, 0x6a, 0x6e };
+ static const int par_op[] = { 0, 0, 3, 3 };
+
+ if (sh > 0) {
+ snprintf (shifter, sizeof (shifter), ", %s #%d",
+ (asr&1 ? "ASR" : "LSL"), sh);
+ } else {
+ shifter[0] = '\0';
+ }
+
+ if (op < 2) {
+ code = arm_code_sat (sat_opcodes[op], cond, sat, Rd, sh, asr, Rm);
+ } else {
+ code = arm_code_par (cond, par_mode[op], sat, Rd, par_op[op], Rm);
+ }
+ ORC_ASM_CODE(p," %s%s %s, #%d, %s%s\n",
+ sat_insn_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd),
+ sat,
+ orc_arm_reg_name (Rm),
+ shifter);
+ orc_arm_emit (p, code);
+}
+
+#define arm_code_rv(op,cond,Rd,Rm) (op|(((cond)&15)<<28)|(((Rd)&15)<<12)|((Rm)&15))
+void
+orc_arm_emit_rv (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rm)
+{
+ uint32_t code;
+ static const uint32_t rv_opcodes[] = { 0x06b00030, 0x06e000b0 };
+ static const char *rv_insn_names[] = { "rev", "rev16" };
+
+ code = arm_code_rv (rv_opcodes[op], cond, Rd, Rm);
+ ORC_ASM_CODE(p," %s%s %s, %s\n",
+ rv_insn_names[op], orc_arm_cond_name(cond),
+ orc_arm_reg_name (Rd), orc_arm_reg_name (Rm));
orc_arm_emit (p, code);
}
+
void orc_arm_do_fixups (OrcCompiler *compiler);
void orc_arm_emit_dp (OrcCompiler *p, int type, OrcArmCond cond, OrcArmDP opcode,
- int S, int Rd, int Rn, int Rm, int shift, int val);
-void orc_arm_emit_mm (OrcCompiler *p, const char *name, OrcArmCond cond, int mode,
- int op, int dest, int src1, int src2);
+ int S, int Rd, int Rn, int Rm, int shift, uint32_t val);
+void orc_arm_emit_par (OrcCompiler *p, int op, int mode, OrcArmCond cond,
+ int Rd, int Rn, int Rm);
+void orc_arm_emit_xt (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rn, int Rm, int r8);
+void orc_arm_emit_pkh (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rn, int Rm, int sh);
+void orc_arm_emit_sat (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int sat, int Rm, int sh, int asr);
+void orc_arm_emit_rv (OrcCompiler *p, int op, OrcArmCond cond,
+ int Rd, int Rm);
/* ALL cpus */
/* data procesing instructions */
/* <op>{<cond>}{s} {<Rd>}, <Rn>, #imm */
-#define orc_arm_emit_and_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_AND,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_eor_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_EOR,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_sub_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_SUB,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_rsb_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_RSB,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_add_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ADD,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_adc_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ADC,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_sbc_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_SBC,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_rsc_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_RSC,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_tst_i(p,cond,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_TST,1, 0,Rn,0,rot,imm)
-#define orc_arm_emit_teq_i(p,cond,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_TEQ,1, 0,Rn,0,rot,imm)
-#define orc_arm_emit_cmp_i(p,cond,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_CMP,1, 0,Rn,0,rot,imm)
-#define orc_arm_emit_cmn_i(p,cond,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_CMN,1, 0,Rn,0,rot,imm)
-#define orc_arm_emit_orr_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ORR,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_mov_i(p,cond,S,Rd,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_MOV,S,Rd, 0,0,rot,imm)
-#define orc_arm_emit_bic_i(p,cond,S,Rd,Rn,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_BIC,S,Rd,Rn,0,rot,imm)
-#define orc_arm_emit_mvn_i(p,cond,S,Rd,rot,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_MVN,S,Rd, 0,0,rot,imm)
+#define orc_arm_emit_and_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_AND,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_eor_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_EOR,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_sub_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_SUB,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_rsb_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_RSB,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_add_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ADD,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_adc_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ADC,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_sbc_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_SBC,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_rsc_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_RSC,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_tst_i(p,cond,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_TST,1, 0,Rn,0,0,imm)
+#define orc_arm_emit_teq_i(p,cond,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_TEQ,1, 0,Rn,0,0,imm)
+#define orc_arm_emit_cmp_i(p,cond,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_CMP,1, 0,Rn,0,0,imm)
+#define orc_arm_emit_cmn_i(p,cond,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_CMN,1, 0,Rn,0,0,imm)
+#define orc_arm_emit_orr_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_ORR,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_mov_i(p,cond,S,Rd,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_MOV,S,Rd, 0,0,0,imm)
+#define orc_arm_emit_bic_i(p,cond,S,Rd,Rn,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_BIC,S,Rd,Rn,0,0,imm)
+#define orc_arm_emit_mvn_i(p,cond,S,Rd,imm) orc_arm_emit_dp(p,0,cond,ORC_ARM_DP_MVN,S,Rd, 0,0,0,imm)
/* <op>{<cond>}{s} {<Rd>}, <Rn>, <Rm> */
#define orc_arm_emit_and_r(p,cond,S,Rd,Rn,Rm) orc_arm_emit_dp(p,1,cond,ORC_ARM_DP_AND,S,Rd,Rn,Rm,0,0)
#define orc_arm_emit_mvn_rrx(p,cond,S,Rd,Rm) orc_arm_emit_dp(p,4,cond,ORC_ARM_DP_MVN,S,Rd, 0,Rm,0,0)
/* parallel instructions */
-#define orc_arm_emit_sadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"sadd16", cond,0x61,0x1,Rd,Rn,Rm)
-#define orc_arm_emit_qadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qadd16", cond,0x62,0x1,Rd,Rn,Rm)
-#define orc_arm_emit_shadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shadd16", cond,0x63,0x1,Rd,Rn,Rm)
-#define orc_arm_emit_uadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uadd16", cond,0x65,0x1,Rd,Rn,Rm)
-#define orc_arm_emit_uqadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqadd16", cond,0x66,0x1,Rd,Rn,Rm)
-#define orc_arm_emit_uhadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhadd16", cond,0x67,0x1,Rd,Rn,Rm)
-
-#define orc_arm_emit_saddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"saddsubx", cond,0x61,0x3,Rd,Rn,Rm)
-#define orc_arm_emit_qaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qaddsubx", cond,0x62,0x3,Rd,Rn,Rm)
-#define orc_arm_emit_shaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shaddsubx",cond,0x63,0x3,Rd,Rn,Rm)
-#define orc_arm_emit_uaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uaddsubx", cond,0x65,0x3,Rd,Rn,Rm)
-#define orc_arm_emit_uqaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqaddsubx",cond,0x66,0x3,Rd,Rn,Rm)
-#define orc_arm_emit_uhaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhaddsubx",cond,0x67,0x3,Rd,Rn,Rm)
-
-#define orc_arm_emit_ssubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"ssubaddx", cond,0x61,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_qsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qsubaddx", cond,0x62,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_shsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shsubaddx",cond,0x63,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_usubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"usubaddx", cond,0x65,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_uqsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqsubaddx",cond,0x66,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_uhsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhsubaddx",cond,0x67,0x5,Rd,Rn,Rm)
-
-#define orc_arm_emit_ssub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"ssub16", cond,0x61,0x7,Rd,Rn,Rm)
-#define orc_arm_emit_qsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qsub16", cond,0x62,0x7,Rd,Rn,Rm)
-#define orc_arm_emit_shsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shsub16", cond,0x63,0x7,Rd,Rn,Rm)
-#define orc_arm_emit_usub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"usub16", cond,0x65,0x7,Rd,Rn,Rm)
-#define orc_arm_emit_uqsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqsub16", cond,0x66,0x7,Rd,Rn,Rm)
-#define orc_arm_emit_uhsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhsub16", cond,0x67,0x7,Rd,Rn,Rm)
-
-#define orc_arm_emit_sadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"sadd8", cond,0x61,0x9,Rd,Rn,Rm)
-#define orc_arm_emit_qadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qadd8", cond,0x62,0x9,Rd,Rn,Rm)
-#define orc_arm_emit_shadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shadd8", cond,0x63,0x9,Rd,Rn,Rm)
-#define orc_arm_emit_uadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uadd8", cond,0x65,0x9,Rd,Rn,Rm)
-#define orc_arm_emit_uqadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqadd8", cond,0x66,0x9,Rd,Rn,Rm)
-#define orc_arm_emit_uhadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhadd8", cond,0x67,0x9,Rd,Rn,Rm)
-
-#define orc_arm_emit_ssub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"ssub8", cond,0x61,0xf,Rd,Rn,Rm)
-#define orc_arm_emit_qsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qsub8", cond,0x62,0xf,Rd,Rn,Rm)
-#define orc_arm_emit_shsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"shsub8", cond,0x63,0xf,Rd,Rn,Rm)
-#define orc_arm_emit_usub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"usub8", cond,0x65,0xf,Rd,Rn,Rm)
-#define orc_arm_emit_uqsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uqsub8", cond,0x66,0xf,Rd,Rn,Rm)
-#define orc_arm_emit_uhsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"uhsub8", cond,0x67,0xf,Rd,Rn,Rm)
-
-#define orc_arm_emit_ssat16(p,cond,Rd,sat,Rm) orc_arm_emit_mm(p,"ssat16", cond,0x6a,0x3,Rd,sat,Rm)
-#define orc_arm_emit_usat16(p,cond,Rd,sat,Rm) orc_arm_emit_mm(p,"usat16", cond,0x6e,0x3,Rd,sat,Rm)
+#define orc_arm_emit_sadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhadd16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,0,5,cond,Rd,Rn,Rm)
+
+#define orc_arm_emit_saddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhaddsubx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,1,5,cond,Rd,Rn,Rm)
+
+#define orc_arm_emit_ssubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_usubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhsubaddx(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,2,5,cond,Rd,Rn,Rm)
+
+#define orc_arm_emit_ssub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_usub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhsub16(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,3,5,cond,Rd,Rn,Rm)
+
+#define orc_arm_emit_sadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhadd8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,4,5,cond,Rd,Rn,Rm)
+
+#define orc_arm_emit_ssub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,0,cond,Rd,Rn,Rm)
+#define orc_arm_emit_qsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,1,cond,Rd,Rn,Rm)
+#define orc_arm_emit_shsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,2,cond,Rd,Rn,Rm)
+#define orc_arm_emit_usub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,3,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uqsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,4,cond,Rd,Rn,Rm)
+#define orc_arm_emit_uhsub8(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,5,5,cond,Rd,Rn,Rm)
+
+/* selection */
+#define orc_arm_emit_sel(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,6,6,cond,Rd,Rn,Rm)
+
+/* saturating add */
+#define orc_arm_emit_qadd(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,7,7, cond,Rd,Rn,Rm)
+#define orc_arm_emit_qsub(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,8,8, cond,Rd,Rn,Rm)
+#define orc_arm_emit_qdadd(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,7,9, cond,Rd,Rn,Rm)
+#define orc_arm_emit_qdsub(p,cond,Rd,Rn,Rm) orc_arm_emit_par(p,8,10,cond,Rd,Rn,Rm)
+
+/* extend instructions */
+/* with ROR #r8, r8 should be a multiple of 8 */
+#define orc_arm_emit_sxtb16_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,0, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,1, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_sxth_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,2, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_uxtb16_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,3, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_uxtb_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,4, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_uxth_r8(p,cond,Rd,Rm,r8) orc_arm_emit_xt(p,5, cond,Rd,15,Rm,r8)
+#define orc_arm_emit_sxtab16_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,6, cond,Rd,Rn,Rm,r8)
+#define orc_arm_emit_sxtab_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,7, cond,Rd,Rn,Rm,r8)
+#define orc_arm_emit_sxtah_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,8, cond,Rd,Rn,Rm,r8)
+#define orc_arm_emit_uxtab16_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,9, cond,Rd,Rn,Rm,r8)
+#define orc_arm_emit_uxtab_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,10,cond,Rd,Rn,Rm,r8)
+#define orc_arm_emit_uxtah_r8(p,cond,Rd,Rn,Rm,r8) orc_arm_emit_xt(p,11,cond,Rd,Rn,Rm,r8)
+/* with out rotate */
+#define orc_arm_emit_sxtb16(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_sxtb(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_sxth(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxtb16(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxtb(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxth(p,cond,Rd,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_sxtab16(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_sxtab(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_sxtah(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxtab16(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxtab(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
+#define orc_arm_emit_uxtah(p,cond,Rd,Rn,Rm) orc_arm_emit_sxtb_r8(p,cond,Rd,Rm,0)
/* misc instructions */
-#define orc_arm_emit_sel(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"sel", cond,0x68,0xb,Rd,Rn,Rm)
-#define orc_arm_emit_qadd(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qadd", cond,0x10,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_qsub(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qsub", cond,0x12,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_qdadd(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qdadd", cond,0x14,0x5,Rd,Rn,Rm)
-#define orc_arm_emit_qdsub(p,cond,Rd,Rn,Rm) orc_arm_emit_mm(p,"qdsub", cond,0x16,0x5,Rd,Rn,Rm)
+/* packing */
+#define orc_arm_emit_pkhbt(p,cond,Rd,Rn,Rm) orc_arm_emit_pkh(p,0,cond,Rd,Rn,Rm,0)
+#define orc_arm_emit_pkhtb(p,cond,Rd,Rn,Rm) orc_arm_emit_pkh(p,1,cond,Rd,Rn,Rm,0)
+/* with [LSL|ASR] #imm */
+#define orc_arm_emit_pkhbt_s(p,cond,Rd,Rn,Rm,lsl) orc_arm_emit_pkh(p,0,cond,Rd,Rn,Rm,lsl)
+#define orc_arm_emit_pkhtb_s(p,cond,Rd,Rn,Rm,asr) orc_arm_emit_pkh(p,1,cond,Rd,Rn,Rm,asr)
+
+/* saturation */
+#define orc_arm_emit_ssat(p,cond,Rd,sat,Rm) orc_arm_emit_sat(p,0,cond,Rd,sat,Rm,0, 0)
+#define orc_arm_emit_usat(p,cond,Rd,sat,Rm) orc_arm_emit_sat(p,1,cond,Rd,sat,Rm,0, 0)
+#define orc_arm_emit_ssat_lsl(p,cond,Rd,sat,Rm,sh) orc_arm_emit_sat(p,0,cond,Rd,sat,Rm,sh,0)
+#define orc_arm_emit_usat_lsl(p,cond,Rd,sat,Rm,sh) orc_arm_emit_sat(p,1,cond,Rd,sat,Rm,sh,0)
+#define orc_arm_emit_ssat_asr(p,cond,Rd,sat,Rm,sh) orc_arm_emit_sat(p,0,cond,Rd,sat,Rm,sh,1)
+#define orc_arm_emit_usat_asr(p,cond,Rd,sat,Rm,sh) orc_arm_emit_sat(p,1,cond,Rd,sat,Rm,sh,1)
+#define orc_arm_emit_ssat16(p,cond,Rd,sat,Rm) orc_arm_emit_sat(p,2,cond,Rd,sat,Rm,0, 0)
+#define orc_arm_emit_usat16(p,cond,Rd,sat,Rm) orc_arm_emit_sat(p,3,cond,Rd,sat,Rm,0, 0)
+
+/* reversing */
+#define orc_arm_emit_rev(p,cond,Rd,Rm) orc_arm_emit_rv (p,0,cond,Rd,Rm)
+#define orc_arm_emit_rev16(p,cond,Rd,Rm) orc_arm_emit_rv (p,1,cond,Rd,Rm)
#endif
orc_arm_emit_label (compiler, 1);
- orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0, 0);
+ orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0);
orc_arm_emit_branch (compiler, ORC_ARM_COND_EQ, 3);
orc_arm_emit_label (compiler, 2);
orc_arm_emit_loop (compiler);
- orc_arm_emit_sub_i (compiler, ORC_ARM_COND_AL, 0, ORC_ARM_IP, ORC_ARM_IP, 0, 1);
- orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0, 0);
+ orc_arm_emit_sub_i (compiler, ORC_ARM_COND_AL, 0, ORC_ARM_IP, ORC_ARM_IP, 1);
+ orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0);
orc_arm_emit_branch (compiler, ORC_ARM_COND_NE, 2);
orc_arm_emit_label (compiler, 3);
if (compiler->vars[k].ptr_register) {
orc_arm_emit_add_i (compiler, ORC_ARM_COND_AL, 0,
compiler->vars[k].ptr_register,
- compiler->vars[k].ptr_register, 0,
+ compiler->vars[k].ptr_register,
compiler->vars[k].size << compiler->loop_shift);
} else {
//orc_arm_emit_add_imm_memoffset (compiler, orc_arm_ptr_size,
orc_arm_emit_##insn_name (p, ORC_ARM_COND_AL, dest, src1, src2); \
}
-#define orc_arm_xt(op,cond,Rn,Rd,Rm,rot) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|((rot)<<10)|(Rm))
-#define orc_arm_emit_sxtb(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06a00070,cond,0xf,Rd,Rm,rot))
-#define orc_arm_emit_sxth(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06b00070,cond,0xf,Rd,Rm,rot))
-#define orc_arm_emit_uxtb(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06e00070,cond,0xf,Rd,Rm,rot))
-#define orc_arm_emit_uxth(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06f00070,cond,0xf,Rd,Rm,rot))
-#define orc_arm_emit_sxtb16(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06800070,cond,0xf,Rd,Rm,rot))
-#define orc_arm_emit_uxtb16(p,cond,Rd,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06c00070,cond,0xf,Rd,Rm,rot))
-
-#define orc_arm_emit_sxtab(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06a00070,cond,Rn,Rd,Rm,rot))
-#define orc_arm_emit_sxtah(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06b00070,cond,Rn,Rd,Rm,rot))
-#define orc_arm_emit_uxtab(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06e00070,cond,Rn,Rd,Rm,rot))
-#define orc_arm_emit_uxtah(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06f00070,cond,Rn,Rd,Rm,rot))
-#define orc_arm_emit_sxtab16(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06800070,cond,Rn,Rd,Rm,rot))
-#define orc_arm_emit_uxtab16(p,cond,Rd,Rn,Rm,rot) orc_arm_emit (p, orc_arm_xt (0x06c00070,cond,Rn,Rd,Rm,rot))
-
-#define orc_arm_pkh(op,cond,Rn,Rd,Rm,sh) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|((sh)<<7)|(Rm))
-#define orc_arm_emit_pkhbt(p,cond,Rd,Rn,Rm,sh) orc_arm_emit (p, orc_arm_xt (0x06800010,cond,Rd,Rn,Rm,sh))
-#define orc_arm_emit_pkhtb(p,cond,Rd,Rn,Rm,sh) orc_arm_emit (p, orc_arm_xt (0x06800050,cond,Rd,Rn,Rm,sh))
-
-#define orc_arm_sat(op,cond,Rd,sat,Rm,sh,a) (op|((cond)<<28)|((sat)<<16)|((Rd)<<12)|((sh)<<7)|((a)<<6)|(Rm))
-#define orc_arm_emit_ssat(p,cond,Rd,sat,Rm,sh,a) orc_arm_emit (p, orc_arm_sat (0x06a00010,cond,Rd,sat,Rm,sh,a))
-#define orc_arm_emit_usat(p,cond,Rd,sat,Rm,sh,a) orc_arm_emit (p, orc_arm_sat (0x06e00010,cond,Rd,sat,Rm,sh,a))
-
-#define orc_arm_rev(op,cond,Rd,Rm) (op|((cond)<<28)|((Rd)<<12)|(Rm))
-#define orc_arm_emit_rev(p,cond,Rd,Rm) orc_arm_emit (p, orc_arm_rev (0x06b00030,cond,Rd,Rm))
-#define orc_arm_emit_rev16(p,cond,Rd,Rm) orc_arm_emit (p, orc_arm_rev (0x06e000b0,cond,Rd,Rm))
-
+/* multiplies */
#define orc_arm_smulxy(cond,x,y,Rd,Rm,Rs) (0x01600080|((cond)<<28)|((Rd)<<16)|((Rs)<<8)|((y)<<6)|((x)<<5)|(Rm))
#define orc_arm_emit_smulbb(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,0,0,Rd,Rm,Rs))
#define orc_arm_emit_smulbt(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,0,1,Rd,Rm,Rs))
void
orc_arm_emit_mov_iw (OrcCompiler *p, int cond, int dest, int val, int loop)
{
- int shift = 0;
-
- while (val && ((val & 3) == 0)) {
- val >>= 2;
- shift++;
- }
/* dest = val */
- orc_arm_emit_mov_i (p, cond, 0, dest, shift, val);
+ orc_arm_emit_mov_i (p, cond, 0, dest, val);
if (loop > 1)
/* 2 words: dest |= dest << 16 */
orc_arm_emit_orr_rsi (p, cond, 0, dest, dest, dest, ORC_ARM_LSL, 16);
void
orc_arm_emit_mov_ib (OrcCompiler *p, int cond, int dest, int val, int loop)
{
- int shift = 0;
-
- while (val && ((val & 3) == 0)) {
- val >>= 2;
- shift++;
- }
/* 1 byte */
- orc_arm_emit_mov_i (p, cond, 0, dest, shift, val);
+ orc_arm_emit_mov_i (p, cond, 0, dest, val);
if (loop > 1)
/* 2 bytes: dest |= dest << 8 */
orc_arm_emit_orr_rsi (p, cond, 0, dest, dest, dest, ORC_ARM_LSL, 8);
int tmp = p->tmpreg;
int type = ORC_PTR_TO_INT(user);
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0);
if (type == 0) {
/* negate tmp = 0 - src1 */
/* signed variant, make a mask, FIXME, instruction constants */
if (type >= 2) {
/* mask for word 0x80008000 */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, mask, 4, 8);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, mask, 0x80000000);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, mask, mask, mask, ORC_ARM_LSR, 16);
if (type >= 3) {
* need instruction wide constants */
if (type <= 1) {
/* clear 0x00010000 */
- orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 8, 1);
+ orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 0x00010000);
if (type == 0) {
/* clear 0x00000100 */
- orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 12, 1);
+ orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 0x00000100);
/* clear 0x01000000 */
- orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 4, 1);
+ orc_arm_emit_bic_i (p, ORC_ARM_COND_AL, 0, dest, dest, 0x01000000);
}
} else if (type >= 2) {
/* already have a mask, use it here */
orc_arm_emit_eor_r (p, ORC_ARM_COND_AL, 0, tmp, src1, src2);
/* clear dest register */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0);
/* tmp = 0 - tmp, set GE flags for 0 bytes */
if (size == 1) {
}
/* make 0xffffffff in tmp */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, tmp, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, tmp, 0);
/* set 0xff for 0 bytes, 0x00 otherwise */
orc_arm_emit_sel (p, ORC_ARM_COND_AL, dest, tmp, dest);
}
/* clear dest register */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0);
/* make 0xffffffff in tmp */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, tmp, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, tmp, 0);
/* set 0x00 for src2 >= src1 bytes, 0xff if src2 < src1 */
orc_arm_emit_sel (p, ORC_ARM_COND_AL, dest, dest, tmp);
int tmp3 = ORC_ARM_V8;
int loop = 1;
- /* first item */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ /* extract and multiply first item */
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, dest, tmp1, tmp2);
if (loop > 1) {
if (loop > 2) {
- /* third item */
+ /* third item, reuse extracted bits for first item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with first */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
}
/* clear upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
- /* second item */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 1);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 1);
+ /* extract and multiply second item */
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 8);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, tmp3, tmp1, tmp2);
if (loop > 2) {
/* forth item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with second */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
}
/* clear upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp3, tmp3, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp3, tmp3);
/* merge results */
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp3, ORC_ARM_LSL, 8);
int loop = 1;
/* first item (and third) */
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, dest, tmp1, tmp2);
if (loop > 1) {
/* third item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with first */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
}
/* extract upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, dest, dest, 8);
/* second item (and fourth) */
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 1);
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 1);
+ orc_arm_emit_sxtb16_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 8);
+ orc_arm_emit_sxtb16_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 8);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, tmp3, tmp1, tmp2);
if (loop > 2) {
/* forth item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with second */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
}
/* extract upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp3, tmp3, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp3, tmp3, 8);
/* merge tmp3 */
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp3, ORC_ARM_LSL, 8);
int loop = 1;
/* first item (and third) */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, dest, tmp1, tmp2);
if (loop > 1) {
/* third item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with first */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, dest, tmp1, 16);
}
/* extract upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, dest, dest, 8);
/* second item (and fourth) */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 1);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 1);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 8);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, tmp3, tmp1, tmp2);
if (loop > 2) {
/* forth item */
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge with second */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, tmp3, tmp3, tmp1, 16);
}
/* extract upper bits */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp3, tmp3, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp3, tmp3, 8);
/* merge tmp3 */
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp3, ORC_ARM_LSL, 8);
/* bigger values, shift and mask out excess bits */
if (val >= size) {
/* too big, clear all */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0);
} else if (val > 0) {
if (loop > 1 && size < 4) {
/* shift, note that we skip the next instructions when 0 */
/* shift */
if (size < 4) {
- if (size == 1)
- /* make loop * 80, position of sign bit after shift */
- orc_arm_emit_mov_ib (p, ORC_ARM_COND_AL, mask, 0x80, loop);
- else
- /* make loop * 8000 */
- orc_arm_emit_mov_iw (p, ORC_ARM_COND_AL, mask, 0x8000, loop);
- /* make mask, save in tmp, we need the original mask */
- orc_arm_emit_sub_rsi (p, ORC_ARM_COND_AL, 0, tmp, mask, mask, ORC_ARM_LSR, val);
-
- /* do the shift */
- orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 1, dest, src1, ORC_ARM_LSR, val);
- /* clear upper bits */
- orc_arm_emit_bic_rsi (p, ORC_ARM_COND_NE, 0, dest, dest, tmp, ORC_ARM_LSL, 1);
-
- /* flip sign bit */
- orc_arm_emit_eor_r (p, ORC_ARM_COND_NE, 0, dest, dest, mask);
- /* extend sign bits */
- if (size == 1)
- orc_arm_emit_usub8 (p, ORC_ARM_COND_NE, dest, dest, mask);
- else
- orc_arm_emit_usub16 (p, ORC_ARM_COND_NE, dest, dest, mask);
+ if (size == 2 && val == 8) {
+ /* half word shift by 8 */
+ orc_arm_emit_sxtb16_r8 (p, ORC_ARM_COND_AL, dest, src1, 8);
+ } else {
+ if (size == 1)
+ /* make loop * 80, position of sign bit after shift */
+ orc_arm_emit_mov_ib (p, ORC_ARM_COND_AL, mask, 0x80, loop);
+ else
+ /* make loop * 8000 */
+ orc_arm_emit_mov_iw (p, ORC_ARM_COND_AL, mask, 0x8000, loop);
+ /* make mask, save in tmp, we need the original mask */
+ orc_arm_emit_sub_rsi (p, ORC_ARM_COND_AL, 0, tmp, mask, mask, ORC_ARM_LSR, val);
+
+ /* do the shift */
+ orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 1, dest, src1, ORC_ARM_LSR, val);
+ /* clear upper bits */
+ orc_arm_emit_bic_rsi (p, ORC_ARM_COND_NE, 0, dest, dest, tmp, ORC_ARM_LSL, 1);
+
+ /* flip sign bit */
+ orc_arm_emit_eor_r (p, ORC_ARM_COND_NE, 0, dest, dest, mask);
+ /* extend sign bits */
+ if (size == 1)
+ orc_arm_emit_usub8 (p, ORC_ARM_COND_NE, dest, dest, mask);
+ else
+ orc_arm_emit_usub16 (p, ORC_ARM_COND_NE, dest, dest, mask);
+ }
} else {
/* full word shift */
orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, src1, ORC_ARM_ASR, val);
/* shift and mask out excess bits */
if (val >= size) {
/* too big, clear all */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, dest, 0);
} else if (val > 0) {
if (size < 4) {
- /* do the shift */
- orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 1, dest, src1, ORC_ARM_LSR, val);
+ if (size == 2 && val == 8) {
+ /* half word shift by 8 */
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, dest, src1, 8);
+ } else {
+ /* do the shift, set S flags */
+ orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 1, dest, src1, ORC_ARM_LSR, val);
- if (size == 1)
- /* make loop * 0x80 */
- orc_arm_emit_mov_ib (p, ORC_ARM_COND_NE, mask, 0x80, loop);
- else
- /* make loop * 0x8000 */
- orc_arm_emit_mov_iw (p, ORC_ARM_COND_NE, mask, 0x8000, loop);
- /* make mask */
- orc_arm_emit_sub_rsi (p, ORC_ARM_COND_NE, 0, mask, mask, mask, ORC_ARM_LSR, val);
+ if (size == 1)
+ /* make loop * 0x80 */
+ orc_arm_emit_mov_ib (p, ORC_ARM_COND_NE, mask, 0x80, loop);
+ else
+ /* make loop * 0x8000 */
+ orc_arm_emit_mov_iw (p, ORC_ARM_COND_NE, mask, 0x8000, loop);
+ /* make mask */
+ orc_arm_emit_sub_rsi (p, ORC_ARM_COND_NE, 0, mask, mask, mask, ORC_ARM_LSR, val);
- /* clear upper bits */
- orc_arm_emit_bic_rsi (p, ORC_ARM_COND_NE, 0, dest, dest, mask, ORC_ARM_LSL, 1);
+ /* clear upper bits */
+ orc_arm_emit_bic_rsi (p, ORC_ARM_COND_NE, 0, dest, dest, mask, ORC_ARM_LSL, 1);
+ }
} else {
+ /* one 4 byte shift, no need for the S flag */
orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, src1, ORC_ARM_LSR, val);
}
}
else
/* make loop * 0x8000 */
orc_arm_emit_mov_iw (p, ORC_ARM_COND_NE, mask, 0x8000, loop);
- /* mask mask */
+ /* make mask */
orc_arm_emit_sub_rsr (p, ORC_ARM_COND_NE, 0, mask, mask, mask, ORC_ARM_LSR, src2);
/* clear bits */
int type = ORC_PTR_TO_INT(user);
/* make 0 */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, zero, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_AL, 0, zero, 0);
/* make 0xffffffff */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, ones, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_AL, 0, ones, 0);
/* dest = src1 - 0 (src1 >= 0 ? 0 : -1) */
if (type == 0)
if (loop == 2) {
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp, src1, src2);
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, dest, tmp, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, dest, tmp, 16);
}
}
static void
orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, ORC_ARM_ASR, 16);
} else {
orc_arm_emit_smultt (p, ORC_ARM_COND_AL, tmp, src1, src2);
- orc_arm_emit_pkhtb (p, ORC_ARM_COND_AL, dest, tmp, dest, 16);
+ orc_arm_emit_pkhtb_s (p, ORC_ARM_COND_AL, dest, tmp, dest, 16);
}
}
static void
int loop = 1;
/* extract first halves */
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp2, src2);
/* multiply, result should fit in the word */
orc_arm_emit_mul (p, ORC_ARM_COND_AL, 0, dest, tmp1, tmp2);
orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, ORC_ARM_LSR, 16);
} else {
/* second halves */
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp1, src1, 2);
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp2, src2, 2);
+ orc_arm_emit_uxth_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 16);
+ orc_arm_emit_uxth_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 16);
orc_arm_emit_mul (p, ORC_ARM_COND_AL, 0, tmp1, tmp1, tmp2);
/* merge */
- orc_arm_emit_pkhtb (p, ORC_ARM_COND_AL, dest, tmp1, dest, 16);
+ orc_arm_emit_pkhtb_s (p, ORC_ARM_COND_AL, dest, tmp1, dest, 16);
}
}
BINARY_MM (subw, ssub16);
int dest = ORC_DEST_ARG (p, insn, 0);
/* reverse sign 0 - src1, assume the value is negative */
- orc_arm_emit_rsb_i (p, ORC_ARM_COND_AL, 1, dest, src1, 0, 0);
+ orc_arm_emit_rsb_i (p, ORC_ARM_COND_AL, 1, dest, src1, 0);
/* if we got negative, copy the original value again */
orc_arm_emit_mov_r (p, ORC_ARM_COND_MI, 0, dest, src1);
orc_arm_emit_add_r (p, ORC_ARM_COND_AL, 1, dest, src1, src2);
/* on overflow, move ffffffff */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_CS, 0, dest, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_CS, 0, dest, 0);
}
static void
arm_rule_avgXl (OrcCompiler *p, void *user, OrcInstruction *insn)
orc_arm_emit_cmp_r (p, ORC_ARM_COND_AL, src1, src2);
/* set to all 0 when not equal */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_NE, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_NE, 0, dest, 0);
/* set to all ff when equal */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_EQ, 0, dest, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_EQ, 0, dest, 0);
}
static void
arm_rule_cmpgtsl (OrcCompiler *p, void *user, OrcInstruction *insn)
orc_arm_emit_cmp_r (p, ORC_ARM_COND_AL, src1, src2);
/* set to all 0 when less or equal */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_LE, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_LE, 0, dest, 0);
/* set to all ff when greater */
- orc_arm_emit_mvn_i (p, ORC_ARM_COND_GT, 0, dest, 0, 0);
+ orc_arm_emit_mvn_i (p, ORC_ARM_COND_GT, 0, dest, 0);
}
static void
int tmp = p->tmpreg;
/* dest = 0 - src1 */
- orc_arm_emit_rsb_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0, 0);
+ orc_arm_emit_rsb_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0);
/* move src1 sign into tmp */
orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, tmp, src1, ORC_ARM_ASR, 31);
orc_arm_emit_sub_r (p, ORC_ARM_COND_AL, 1, dest, src1, src2);
/* overflow, move 00000000 */
- orc_arm_emit_mov_i (p, ORC_ARM_COND_CC, 0, dest, 0, 0);
+ orc_arm_emit_mov_i (p, ORC_ARM_COND_CC, 0, dest, 0);
}
static void
if (loop == 1) {
/* single byte */
- orc_arm_emit_sxtb (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_sxtb (p, ORC_ARM_COND_AL, dest, src1);
} else {
/* two bytes */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, src1, src1, 8);
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, dest, dest, 0);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, src1, src1, 8);
+ orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, dest, dest);
}
}
if (loop == 1) {
/* single byte */
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1);
} else {
/* two bytes */
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, src1, src1, 8);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest, 0);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, src1, src1, 8);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
}
}
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_sxth (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_sxth (p, ORC_ARM_COND_AL, dest, src1);
}
static void
arm_rule_convuwl (OrcCompiler *p, void *user, OrcInstruction *insn)
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src1);
}
static void
if (loop == 2) {
/* two words */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
if (loop == 2) {
/* two words */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
if (loop == 2) {
/* two words */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
int loop = 1;
/* sign bias */
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 8, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0x00008000);
if (loop == 2)
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 1, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, dest, 0x80000000);
/* saturate to signed region */
orc_arm_emit_usat16 (p, ORC_ARM_COND_AL, dest, 7, dest);
if (loop == 2) {
/* pack two words */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
int loop = 1;
/* sign bias */
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 8, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0x00008000);
if (loop == 2)
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 1, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, dest, 0x80000000);
/* saturate to unsigned region */
orc_arm_emit_usat16 (p, ORC_ARM_COND_AL, dest, 8, dest);
if (loop == 2) {
/* pack two words */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_ssat (p, ORC_ARM_COND_AL, dest, 16, src1, 0, 0);
+ orc_arm_emit_ssat (p, ORC_ARM_COND_AL, dest, 16, src1);
}
static void
arm_rule_convsuslw (OrcCompiler *p, void *user, OrcInstruction *insn)
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 16, src1, 0, 0);
+ orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 16, src1);
}
static void
arm_rule_convusslw (OrcCompiler *p, void *user, OrcInstruction *insn)
int dest = ORC_DEST_ARG (p, insn, 0);
/* sign bias */
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 1, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0x80000000);
/* saturate to signed region */
- orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 7, dest, 0, 0);
+ orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 15, dest);
}
static void
arm_rule_convuuslw (OrcCompiler *p, void *user, OrcInstruction *insn)
int dest = ORC_DEST_ARG (p, insn, 0);
/* sign bias */
- orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 1, 2);
+ orc_arm_emit_eor_i (p, ORC_ARM_COND_AL, 0, dest, src1, 0x80000000);
/* saturate to unsigned region */
- orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 8, dest, 0, 0);
+ orc_arm_emit_usat (p, ORC_ARM_COND_AL, dest, 16, dest);
}
static void
int loop = 1;
/* first item */
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, dest, tmp1, tmp2);
if (loop > 1) {
/* second item */
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 1);
- orc_arm_emit_sxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 1);
+ orc_arm_emit_sxtb16_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 8);
+ orc_arm_emit_sxtb16_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 8);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge results */
int loop = 1;
/* first item */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 0);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, dest, tmp1, tmp2);
if (loop > 1) {
/* second item */
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp1, src1, 1);
- orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp2, src2, 1);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp1, src1, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, tmp2, src2, 8);
orc_arm_emit_smulbb (p, ORC_ARM_COND_AL, tmp1, tmp1, tmp2);
/* merge results */
int dest = ORC_DEST_ARG (p, insn, 0);
int tmp1 = p->tmpreg;
- orc_arm_emit_sxth (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_sxth (p, ORC_ARM_COND_AL, dest, src2, 0);
+ orc_arm_emit_sxth (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_sxth (p, ORC_ARM_COND_AL, dest, src2);
orc_arm_emit_mul (p, ORC_ARM_COND_AL, 0, dest, tmp1, dest);
}
int dest = ORC_DEST_ARG (p, insn, 0);
int tmp1 = p->tmpreg;
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp1, src1, 0);
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src2, 0);
+ orc_arm_emit_uxth (p, ORC_ARM_COND_AL, tmp1, src1);
+ orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src2);
orc_arm_emit_mul (p, ORC_ARM_COND_AL, 0, dest, tmp1, dest);
}
int src2 = ORC_SRC_ARG (p, insn, 1);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_pkhbt (p, ORC_ARM_COND_AL, dest, src1, src2, 16);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, src1, src2, 16);
}
static void
arm_rule_mergebw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
+ /* BINARY_BW(mergebw, "((uint8_t)%s) | ((uint8_t)%s << 8)") */
int src1 = ORC_SRC_ARG (p, insn, 0);
int src2 = ORC_SRC_ARG (p, insn, 1);
int dest = ORC_DEST_ARG (p, insn, 0);
int tmp = p->tmpreg;
int loop = 1;
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1, 0);
-
if (loop == 1) {
/* 1 word */
+ orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, src2, ORC_ARM_LSL, 8);
} else {
/* 2 words */
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, tmp, src2, 0);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, dest, src1, src1, 8);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, dest);
+ orc_arm_emit_pkhbt_s (p, ORC_ARM_COND_AL, tmp, src2, src2, 8);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, tmp, tmp);
orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp, ORC_ARM_LSL, 8);
}
}
static void
arm_rule_select0wb (OrcCompiler *p, void *user, OrcInstruction *insn)
{
+ /* UNARY_WB(select0wb, "(uint16_t)%s & 0xff") */
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- int tmp = p->tmpreg;
int loop = 1;
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1, 0);
-
- if (loop == 2) {
+ if (loop == 1) {
+ /* 1 words */
+ /* NOP */
+ } else {
/* 2 words */
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, tmp, src1, 2);
- orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp, ORC_ARM_LSL, 8);
+ orc_arm_emit_uxtb16 (p, ORC_ARM_COND_AL, dest, src1);
+ orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
static void
arm_rule_select1wb (OrcCompiler *p, void *user, OrcInstruction *insn)
{
+ /* UNARY_WB(select1wb, "((uint16_t)%s >> 8)&0xff") */
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- int tmp = p->tmpreg;
int loop = 1;
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, dest, src1, 1);
-
- if (loop == 2) {
+ if (loop == 1) {
+ /* 1 words */
+ orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, src1, ORC_ARM_LSR, 8);
+ } else {
/* 2 words */
- orc_arm_emit_uxtb (p, ORC_ARM_COND_AL, tmp, src1, 3);
- orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, tmp, ORC_ARM_LSL, 8);
+ orc_arm_emit_uxtb16_r8 (p, ORC_ARM_COND_AL, dest, src1, 8);
+ orc_arm_emit_orr_rsi (p, ORC_ARM_COND_AL, 0, dest, dest, dest, ORC_ARM_LSR, 8);
}
}
static void
arm_rule_select0lw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- int src1 = ORC_SRC_ARG (p, insn, 0);
- int dest = ORC_DEST_ARG (p, insn, 0);
-
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src1, 0);
+ /* UNARY_LW(select0lw, "(uint32_t)%s & 0xffff") */
+ /* NOP */
}
static void
arm_rule_select1lw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
+ /* UNARY_LW(select1lw, "((uint32_t)%s >> 16)&0xffff") */
int src1 = ORC_SRC_ARG (p, insn, 0);
int dest = ORC_DEST_ARG (p, insn, 0);
- orc_arm_emit_uxth (p, ORC_ARM_COND_AL, dest, src1, 2);
+ orc_arm_emit_mov_rsi (p, ORC_ARM_COND_AL, 0, dest, src1, ORC_ARM_LSR, 16);
}
static void