X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fx86_64%2Fcodegen.c;h=dc42a9a966075f1b9cb7a297edadb8102c9785d2;hb=219e4a46e3d127d3c0883ee2e8635b4fe3c94d60;hp=03bb1faf407726116c6bb6d84e17abb211aa783f;hpb=5fd66d7079226750d364952b1b305d97e38f808b;p=cacao.git diff --git a/src/vm/jit/x86_64/codegen.c b/src/vm/jit/x86_64/codegen.c index 03bb1faf4..dc42a9a96 100644 --- a/src/vm/jit/x86_64/codegen.c +++ b/src/vm/jit/x86_64/codegen.c @@ -2486,8 +2486,6 @@ gen_method: classinfo *super; s4 superindex; - s4 looptarget; - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { super = NULL; superindex = 0; @@ -2570,64 +2568,38 @@ gen_method: M_ALD(REG_ITMP3, RIP, disp); if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) { - M_AADD_IMM(-32, REG_SP); /* need some stack */ - if (s1 == REG_ITMP1) - M_AST(REG_ITMP1, REG_SP, -8 + 32); - - M_ALD(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 */ - - emit_label_beq(cd, BRANCH_LABEL_6); /* good */ - - M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); - emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1); - - M_AST(REG_ITMP3, REG_SP, -16 + 32); - M_AST_IMM32(0, REG_SP, -24 + 32); - M_ALD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow)); - looptarget = cd->mcodeptr - cd->mcodebase; - - M_ALD(REG_ITMP3, REG_SP, -24 + 32); - M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_overflow_length), REG_ITMP3); - emit_label_bge(cd, BRANCH_LABEL_9); /* throw */ - - *(cd->mcodeptr++) = 0x4e; - *(cd->mcodeptr++) = 0x8b; - *(cd->mcodeptr++) = 0x1c; - *(cd->mcodeptr++) = 0xd8; - /* movq (ITMP1, ITMP3, 8), ITMP3 */ - - M_LCMP_MEMBASE(REG_SP, -16 + 32, REG_ITMP3); - emit_label_beq(cd, BRANCH_LABEL_7); /* good */ - - M_LINC_MEMBASE(REG_SP, -24 + 32); - M_JMP_IMM2(looptarget - (cd->mcodeptr - cd->mcodebase) - 2); /* 1 byte displacement */ - - emit_label(cd, BRANCH_LABEL_9); - M_AADD_IMM(32, REG_SP); /* restore stack frame */ - M_ALD_MEM(REG_ITMP3, TRAP_ClassCastException); - - emit_label(cd, BRANCH_LABEL_7); - - emit_label(cd, BRANCH_LABEL_6); - - if (s1 == REG_ITMP1) - M_ALD(REG_ITMP1, REG_SP, -8 + 32); - M_AADD_IMM(32, REG_SP); + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset)); + M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3); + emit_label_beq(cd, BRANCH_LABEL_6); /* good */ + + if (super == NULL) { + M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); + emit_label_bne(cd, BRANCH_LABEL_10); /* throw */ + } + + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth)); + 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)); + 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); + if (super == NULL) + emit_label(cd, BRANCH_LABEL_10); + + /* reload s1, might have been destroyed */ + emit_load_s1(jd, iptr, REG_ITMP1); + M_ALD_MEM(s1, TRAP_ClassCastException); + + emit_label(cd, BRANCH_LABEL_7); + emit_label(cd, BRANCH_LABEL_6); + /* reload s1, might have been destroyed */ + 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(ITMP1), ITMP2 */ - + M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3); emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1); } @@ -2682,8 +2654,6 @@ gen_method: classinfo *super; s4 superindex; - s4 looptarget; - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { super = NULL; superindex = 0; @@ -2775,74 +2745,47 @@ gen_method: M_ALD(REG_ITMP3, RIP, disp); if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) { - M_AADD_IMM(-32, REG_SP); /* need some stack */ - M_ALD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset)); + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset)); + 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_BSEXT(d, d); + } else + M_LINC(d); + emit_label_br(cd, BRANCH_LABEL_6); /* true */ + emit_label(cd, BRANCH_LABEL_8); + + if (super == NULL) { + M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); + emit_label_bne(cd, BRANCH_LABEL_10); /* false */ + } - *(cd->mcodeptr++) = 0x4d; - *(cd->mcodeptr++) = 0x3b; - *(cd->mcodeptr++) = 0x1c; - *(cd->mcodeptr++) = 0x02; - /* cmp (ITMP2, ITMP1, 1), ITMP3 */ + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth)); + M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1); + emit_label_bgt(cd, BRANCH_LABEL_9); /* false */ - emit_label_bne(cd, BRANCH_LABEL_6); - if (d == REG_ITMP2) { + M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow)); + M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3); M_SETE(d); - M_BSEXT(d, d); - } else - M_LINC(d); - emit_label_br(cd, BRANCH_LABEL_7); /* done, true */ - - emit_label(cd, BRANCH_LABEL_6); - - M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); - emit_label_bne(cd, BRANCH_LABEL_6); /* done, false */ - - M_AST(REG_ITMP3, REG_SP, -16 + 32); - M_AST_IMM32(0, REG_SP, -24 + 32); - M_ALD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow)); - looptarget = cd->mcodeptr - cd->mcodebase; - - M_ALD(REG_ITMP3, REG_SP, -24 + 32); - M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_overflow_length), REG_ITMP3); - emit_label_bge(cd, BRANCH_LABEL_8); /* done, false */ - - *(cd->mcodeptr++) = 0x4e; - *(cd->mcodeptr++) = 0x8b; - *(cd->mcodeptr++) = 0x1c; - *(cd->mcodeptr++) = 0xd8; - /* movq (ITMP1, ITMP3, 8), ITMP3 */ - - M_LCMP_MEMBASE(REG_SP, -16 + 32, REG_ITMP3); - emit_label_bne(cd, BRANCH_LABEL_9); - if (d == REG_ITMP2) { - M_SETE(d); - M_BSEXT(d, d); - } else - M_LINC(d); - emit_label_br(cd, BRANCH_LABEL_10); /* done, true */ - emit_label(cd, BRANCH_LABEL_9); - - M_LINC_MEMBASE(REG_SP, -24 + 32); - M_JMP_IMM2(looptarget - (cd->mcodeptr - cd->mcodebase) - 2); /* 1 byte displacement */ + if (d == REG_ITMP2) { + M_BSEXT(d, d); - emit_label(cd, BRANCH_LABEL_8); - emit_label(cd, BRANCH_LABEL_6); + emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */ + } - if (d == REG_ITMP2) - M_CLR(d); + emit_label(cd, BRANCH_LABEL_9); + if (super == NULL) + emit_label(cd, BRANCH_LABEL_10); + if (d == REG_ITMP2) { + M_CLR(d); - emit_label(cd, BRANCH_LABEL_10); - emit_label(cd, BRANCH_LABEL_7); - M_AADD_IMM(32, REG_SP); + emit_label(cd, BRANCH_LABEL_7); + } + 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(ITMP1), ITMP2 */ - + M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3); M_SETE(d); if (d == REG_ITMP2) M_BSEXT(d, d);