if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
-
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x1c;
- *(cd->mcodeptr++) = 0x02;
- /* cmp (ITMP2, ITMP1, 1), ITMP3 */
-
+ M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
emit_label_beq(cd, BRANCH_LABEL_6); /* good */
if (super == NULL) {
}
M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
- *(cd->mcodeptr++) = 0x41;
- *(cd->mcodeptr++) = 0x39;
- *(cd->mcodeptr++) = 0x42;
- *(cd->mcodeptr++) = OFFSET(vftbl_t, subtype_depth);
- /* cmpl ITMP1, subtype_depth(ITMP2) */
- emit_label_blt(cd, BRANCH_LABEL_9); /* throw */
+ M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
+ emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
-
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x5c;
- *(cd->mcodeptr++) = 0xc2;
- *(cd->mcodeptr++) = -8*DISPLAY_SIZE;
- /* cmp -8*DISPL(ITMP2, ITMP1, 8), ITMP3 */
-
+ M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
emit_label_beq(cd, BRANCH_LABEL_7); /* good */
emit_label(cd, BRANCH_LABEL_9);
emit_load_s1(jd, iptr, REG_ITMP1);
}
else {
- assert(super->vftbl->subtype_offset < 0x80);
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x5a;
- *(cd->mcodeptr++) = super->vftbl->subtype_offset;
- /* cmp off(ITMP2), ITMP3 */
-
+ M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
}
if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
-
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x1c;
- *(cd->mcodeptr++) = 0x02;
- /* cmp (ITMP2, ITMP1, 1), ITMP3 */
-
+ M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
if (d == REG_ITMP2) {
M_SETE(d);
}
M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
- *(cd->mcodeptr++) = 0x41;
- *(cd->mcodeptr++) = 0x39;
- *(cd->mcodeptr++) = 0x42;
- *(cd->mcodeptr++) = OFFSET(vftbl_t, subtype_depth);
- /* cmpl ITMP1, subtype_depth(ITMP2) */
- emit_label_blt(cd, BRANCH_LABEL_9); /* false */
+ M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
+ emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
-
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x5c;
- *(cd->mcodeptr++) = 0xc2;
- *(cd->mcodeptr++) = -8*DISPLAY_SIZE;
- /* cmp -8*DISPL(ITMP2, ITMP1, 8), ITMP3 */
-
+ M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
M_SETE(d);
if (d == REG_ITMP2) {
M_BSEXT(d, d);
emit_label(cd, BRANCH_LABEL_6);
}
else {
- assert(super->vftbl->subtype_offset < 0x80);
- *(cd->mcodeptr++) = 0x4d;
- *(cd->mcodeptr++) = 0x3b;
- *(cd->mcodeptr++) = 0x5a;
- *(cd->mcodeptr++) = super->vftbl->subtype_offset;
- /* cmp off(ITMP2), ITMP3 */
-
+ M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
M_SETE(d);
if (d == REG_ITMP2)
M_BSEXT(d, d);
#define M_LCMP_IMM(a,b) emit_alu_imm_reg(cd, ALU_CMP, (a), (b))
#define M_LCMP_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_CMP, (a), (b), (c))
#define M_LCMP_MEMBASE(a,b,c) emit_alu_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_LCMP_MEMINDEX(a,b,c,d,e) emit_alul_memindex_reg(cd, ALU_CMP, (b), (a), (c), (d), (e))
#define M_ICMP(a,b) emit_alul_reg_reg(cd, ALU_CMP, (a), (b))
#define M_ICMP_IMM(a,b) emit_alul_imm_reg(cd, ALU_CMP, (a), (b))
#define M_ICMP_IMM32(a,b) emit_alul_imm32_reg(cd, ALU_CMP, (a), (b))
#define M_ICMP_IMM_MEMBASE(a,b,c) emit_alul_imm_membase(cd, ALU_CMP, (a), (b), (c))
#define M_ICMP_MEMBASE(a,b,c) emit_alul_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_ICMP_MEMINDEX(a,b,c,d,e) emit_alu_memindex_reg(cd, ALU_CMP, (b), (a), (c), (d), (e))
#define M_BEQ(disp) emit_jcc(cd, CC_E, (disp))
#define M_BNE(disp) emit_jcc(cd, CC_NE, (disp))
}
}
+void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
+{
+ emit_rex(1,(reg),(indexreg),(basereg));
+ *(cd->mcodeptr++) = (((opc)) << 3) + 3;
+ emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
+}
+
+void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
+{
+ emit_rex(0,(reg),(indexreg),(basereg));
+ *(cd->mcodeptr++) = (((opc)) << 3) + 3;
+ emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
+}
void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
emit_rex(1,(reg),0,(dreg));
void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
+void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg);
void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg);