Mercurial > repos > blastem
comparison z80_to_x86.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | 6fdac0108e47 |
children | 3e591869d135 |
comparison
equal
deleted
inserted
replaced
1692:5dacaef602a7 | 2053:3414a4423de1 |
---|---|
353 if (size != SZ_B) { | 353 if (size != SZ_B) { |
354 num_cycles += 2; | 354 num_cycles += 2; |
355 } | 355 } |
356 if (inst->reg == Z80_I || inst->ea_reg == Z80_I || inst->reg == Z80_R || inst->ea_reg == Z80_R) { | 356 if (inst->reg == Z80_I || inst->ea_reg == Z80_I || inst->reg == Z80_R || inst->ea_reg == Z80_R) { |
357 num_cycles += 1; | 357 num_cycles += 1; |
358 } else if (inst->reg == Z80_USE_IMMED) { | |
359 num_cycles += 3; | |
358 } | 360 } |
359 break; | 361 break; |
360 case Z80_IMMED: | 362 case Z80_IMMED: |
361 num_cycles += size == SZ_B ? 3 : 6; | 363 num_cycles += size == SZ_B ? 3 : 6; |
362 break; | 364 break; |
872 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 874 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
873 num_cycles += 8; | 875 num_cycles += 8; |
874 } else if(inst->addr_mode == Z80_IMMED) { | 876 } else if(inst->addr_mode == Z80_IMMED) { |
875 num_cycles += 3; | 877 num_cycles += 3; |
876 } else if(z80_size(inst) == SZ_W) { | 878 } else if(z80_size(inst) == SZ_W) { |
877 num_cycles += 4; | 879 num_cycles += 7; |
878 } | 880 } |
879 cycles(&opts->gen, num_cycles); | 881 cycles(&opts->gen, num_cycles); |
880 translate_z80_reg(inst, &dst_op, opts); | 882 translate_z80_reg(inst, &dst_op, opts); |
881 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); | 883 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); |
882 if (dst_op.mode == MODE_REG_DIRECT) { | 884 if (dst_op.mode == MODE_REG_DIRECT) { |
940 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 942 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
941 num_cycles += 8; | 943 num_cycles += 8; |
942 } else if(inst->addr_mode == Z80_IMMED) { | 944 } else if(inst->addr_mode == Z80_IMMED) { |
943 num_cycles += 3; | 945 num_cycles += 3; |
944 } else if(z80_size(inst) == SZ_W) { | 946 } else if(z80_size(inst) == SZ_W) { |
945 num_cycles += 4; | 947 num_cycles += 7; |
946 } | 948 } |
947 cycles(&opts->gen, num_cycles); | 949 cycles(&opts->gen, num_cycles); |
948 translate_z80_reg(inst, &dst_op, opts); | 950 translate_z80_reg(inst, &dst_op, opts); |
949 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); | 951 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); |
950 if (dst_op.mode == MODE_REG_DIRECT) { | 952 if (dst_op.mode == MODE_REG_DIRECT) { |
1071 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1073 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
1072 num_cycles += 8; | 1074 num_cycles += 8; |
1073 } else if(inst->addr_mode == Z80_IMMED) { | 1075 } else if(inst->addr_mode == Z80_IMMED) { |
1074 num_cycles += 3; | 1076 num_cycles += 3; |
1075 } else if(z80_size(inst) == SZ_W) { | 1077 } else if(z80_size(inst) == SZ_W) { |
1076 num_cycles += 4; | 1078 num_cycles += 7; |
1077 } | 1079 } |
1078 cycles(&opts->gen, num_cycles); | 1080 cycles(&opts->gen, num_cycles); |
1079 translate_z80_reg(inst, &dst_op, opts); | 1081 translate_z80_reg(inst, &dst_op, opts); |
1080 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); | 1082 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); |
1081 if (dst_op.mode == MODE_REG_DIRECT) { | 1083 if (dst_op.mode == MODE_REG_DIRECT) { |
1259 break; | 1261 break; |
1260 case Z80_INC: | 1262 case Z80_INC: |
1261 case Z80_DEC: | 1263 case Z80_DEC: |
1262 if(z80_size(inst) == SZ_W) { | 1264 if(z80_size(inst) == SZ_W) { |
1263 num_cycles += 2; | 1265 num_cycles += 2; |
1266 } else if (inst->addr_mode == Z80_REG_INDIRECT) { | |
1267 num_cycles += 1; | |
1268 } else if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | |
1269 num_cycles += 9; | |
1264 } | 1270 } |
1265 cycles(&opts->gen, num_cycles); | 1271 cycles(&opts->gen, num_cycles); |
1266 translate_z80_reg(inst, &dst_op, opts); | 1272 translate_z80_reg(inst, &dst_op, opts); |
1267 if (dst_op.mode == MODE_UNUSED) { | 1273 if (dst_op.mode == MODE_UNUSED) { |
1268 translate_z80_ea(inst, &dst_op, opts, READ, MODIFY); | 1274 translate_z80_ea(inst, &dst_op, opts, READ, MODIFY); |
1851 ror_ir(code, 8, opts->gen.scratch1, SZ_W); | 1857 ror_ir(code, 8, opts->gen.scratch1, SZ_W); |
1852 call(code, opts->write_8); | 1858 call(code, opts->write_8); |
1853 break; | 1859 break; |
1854 case Z80_BIT: { | 1860 case Z80_BIT: { |
1855 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1861 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
1856 num_cycles += 8; | 1862 num_cycles += 4; |
1857 } | 1863 } |
1858 cycles(&opts->gen, num_cycles); | 1864 cycles(&opts->gen, num_cycles); |
1859 uint8_t bit; | 1865 uint8_t bit; |
1860 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | 1866 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { |
1861 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | 1867 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; |
1912 } | 1918 } |
1913 break; | 1919 break; |
1914 } | 1920 } |
1915 case Z80_SET: { | 1921 case Z80_SET: { |
1916 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1922 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
1917 num_cycles += 8; | 1923 num_cycles += 4; |
1918 } | 1924 } |
1919 cycles(&opts->gen, num_cycles); | 1925 cycles(&opts->gen, num_cycles); |
1920 uint8_t bit; | 1926 uint8_t bit; |
1921 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | 1927 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { |
1922 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | 1928 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; |
1981 } | 1987 } |
1982 break; | 1988 break; |
1983 } | 1989 } |
1984 case Z80_RES: { | 1990 case Z80_RES: { |
1985 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { | 1991 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { |
1986 num_cycles += 8; | 1992 num_cycles += 4; |
1987 } | 1993 } |
1988 cycles(&opts->gen, num_cycles); | 1994 cycles(&opts->gen, num_cycles); |
1989 uint8_t bit; | 1995 uint8_t bit; |
1990 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | 1996 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { |
1991 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; | 1997 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; |
2319 } | 2325 } |
2320 cycles(&opts->gen, num_cycles);//T States: 4 3/4 | 2326 cycles(&opts->gen, num_cycles);//T States: 4 3/4 |
2321 if (inst->addr_mode == Z80_IMMED_INDIRECT) { | 2327 if (inst->addr_mode == Z80_IMMED_INDIRECT) { |
2322 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_B); | 2328 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_B); |
2323 } else { | 2329 } else { |
2324 zreg_to_native(opts, Z80_C, opts->gen.scratch2); | 2330 zreg_to_native(opts, Z80_C, opts->gen.scratch1); |
2325 } | 2331 } |
2326 call(code, opts->read_io); | 2332 call(code, opts->read_io); |
2327 if (inst->addr_mode != Z80_IMMED_INDIRECT) { | 2333 if (inst->addr_mode != Z80_IMMED_INDIRECT) { |
2328 or_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_B); | 2334 or_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_B); |
2329 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); | 2335 mov_irdisp(code, 0, opts->gen.context_reg, zf_off(ZF_H), SZ_B); |
2591 jmp(code, start); | 2597 jmp(code, start); |
2592 *done = code->cur - (done + 1); | 2598 *done = code->cur - (done + 1); |
2593 break; | 2599 break; |
2594 } | 2600 } |
2595 case Z80_OUT: | 2601 case Z80_OUT: |
2596 if (inst->reg == Z80_A) { | 2602 if (inst->addr_mode == Z80_IMMED_INDIRECT) { |
2597 num_cycles += 3; | 2603 num_cycles += 3; |
2598 } | 2604 } |
2599 cycles(&opts->gen, num_cycles);//T States: 4 3/4 | 2605 cycles(&opts->gen, num_cycles);//T States: 4 3/4 |
2600 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { | 2606 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { |
2601 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B); | 2607 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B); |
2656 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); | 2662 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); |
2657 } | 2663 } |
2658 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 2664 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
2659 break; | 2665 break; |
2660 case Z80_OTIR: { | 2666 case Z80_OTIR: { |
2661 code_ptr start = code->cur; | |
2662 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 | 2667 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 |
2663 //read from (HL) | 2668 //read from (HL) |
2664 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); | 2669 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); |
2665 call(code, opts->read_8);//T states 3 | 2670 call(code, opts->read_8);//T states 3 |
2666 //undocumented N flag behavior | 2671 //undocumented N flag behavior |
2756 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); | 2761 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); |
2757 } | 2762 } |
2758 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); | 2763 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); |
2759 break; | 2764 break; |
2760 case Z80_OTDR: { | 2765 case Z80_OTDR: { |
2761 code_ptr start = code->cur; | |
2762 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 | 2766 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 |
2763 //read from (HL) | 2767 //read from (HL) |
2764 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); | 2768 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); |
2765 call(code, opts->read_8);//T states 3 | 2769 call(code, opts->read_8);//T states 3 |
2766 //undocumented N flag behavior | 2770 //undocumented N flag behavior |
3407 options->gen.handle_cycle_limit_int = code->cur; | 3411 options->gen.handle_cycle_limit_int = code->cur; |
3408 neg_r(code, options->gen.cycles, SZ_D); | 3412 neg_r(code, options->gen.cycles, SZ_D); |
3409 add_rdispr(code, options->gen.context_reg, offsetof(z80_context, target_cycle), options->gen.cycles, SZ_D); | 3413 add_rdispr(code, options->gen.context_reg, offsetof(z80_context, target_cycle), options->gen.cycles, SZ_D); |
3410 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); | 3414 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); |
3411 jcc(code, CC_B, skip_int); | 3415 jcc(code, CC_B, skip_int); |
3416 //check that we are not past the end of interrupt pulse | |
3417 cmp_rrdisp(code, options->gen.cycles, options->gen.context_reg, offsetof(z80_context, int_pulse_end), SZ_D); | |
3418 jcc(code, CC_B, skip_int); | |
3412 //set limit to the cycle limit | 3419 //set limit to the cycle limit |
3413 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.scratch2, SZ_D); | 3420 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sync_cycle), options->gen.scratch2, SZ_D); |
3414 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, target_cycle), SZ_D); | 3421 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, target_cycle), SZ_D); |
3415 neg_r(code, options->gen.cycles, SZ_D); | 3422 neg_r(code, options->gen.cycles, SZ_D); |
3416 add_rr(code, options->gen.scratch2, options->gen.cycles, SZ_D); | 3423 add_rr(code, options->gen.scratch2, options->gen.cycles, SZ_D); |
3418 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); | 3425 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); |
3419 code_ptr is_nmi = code->cur + 1; | 3426 code_ptr is_nmi = code->cur + 1; |
3420 jcc(code, CC_NZ, is_nmi); | 3427 jcc(code, CC_NZ, is_nmi); |
3421 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); | 3428 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); |
3422 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); | 3429 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); |
3430 cycles(&options->gen, 6); //interupt ack cycle | |
3423 code_ptr after_int_disable = code->cur + 1; | 3431 code_ptr after_int_disable = code->cur + 1; |
3424 jmp(code, after_int_disable); | 3432 jmp(code, after_int_disable); |
3425 *is_nmi = code->cur - (is_nmi + 1); | 3433 *is_nmi = code->cur - (is_nmi + 1); |
3426 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, iff1), options->gen.scratch2, SZ_B); | 3434 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, iff1), options->gen.scratch2, SZ_B); |
3427 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); | 3435 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); |
3428 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); | 3436 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); |
3437 cycles(&options->gen, 5); //NMI processing cycles | |
3429 *after_int_disable = code->cur - (after_int_disable + 1); | 3438 *after_int_disable = code->cur - (after_int_disable + 1); |
3430 cycles(&options->gen, 7); | |
3431 //save return address (in scratch1) to Z80 stack | 3439 //save return address (in scratch1) to Z80 stack |
3432 sub_ir(code, 2, options->regs[Z80_SP], SZ_W); | 3440 sub_ir(code, 2, options->regs[Z80_SP], SZ_W); |
3433 mov_rr(code, options->regs[Z80_SP], options->gen.scratch2, SZ_W); | 3441 mov_rr(code, options->regs[Z80_SP], options->gen.scratch2, SZ_W); |
3434 //we need to do check_cycles and cycles outside of the write_8 call | 3442 //we need to do check_cycles and cycles outside of the write_8 call |
3435 //so that the stack has the correct depth if we need to return to C | 3443 //so that the stack has the correct depth if we need to return to C |
3451 //dispose of return address as we'll be jumping somewhere else | 3459 //dispose of return address as we'll be jumping somewhere else |
3452 add_ir(code, 16, RSP, SZ_PTR); | 3460 add_ir(code, 16, RSP, SZ_PTR); |
3453 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); | 3461 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); |
3454 is_nmi = code->cur + 1; | 3462 is_nmi = code->cur + 1; |
3455 jcc(code, CC_NZ, is_nmi); | 3463 jcc(code, CC_NZ, is_nmi); |
3456 cycles(&options->gen, 6); //interupt ack cycle | |
3457 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack | 3464 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack |
3458 //which is conveniently rst $38, i.e. the same thing that im 1 does | 3465 //which is conveniently rst $38, i.e. the same thing that im 1 does |
3459 //check interrupt mode | 3466 //check interrupt mode |
3460 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B); | 3467 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B); |
3461 code_ptr im2 = code->cur + 1; | 3468 code_ptr im2 = code->cur + 1; |
3462 jcc(code, CC_Z, im2); | 3469 jcc(code, CC_Z, im2); |
3463 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); | 3470 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); |
3471 cycles(&options->gen, 1); //total time for mode 0/1 is 13 t-states | |
3464 code_ptr after_int_dest = code->cur + 1; | 3472 code_ptr after_int_dest = code->cur + 1; |
3465 jmp(code, after_int_dest); | 3473 jmp(code, after_int_dest); |
3466 *im2 = code->cur - (im2 + 1); | 3474 *im2 = code->cur - (im2 + 1); |
3467 //read vector address from I << 8 | vector | 3475 //read vector address from I << 8 | vector |
3468 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B); | 3476 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B); |
3499 code->stack_off = tmp_stack_off; | 3507 code->stack_off = tmp_stack_off; |
3500 | 3508 |
3501 //HACK | 3509 //HACK |
3502 options->gen.address_size = SZ_D; | 3510 options->gen.address_size = SZ_D; |
3503 options->gen.address_mask = io_address_mask; | 3511 options->gen.address_mask = io_address_mask; |
3512 options->gen.bus_cycles = 4; | |
3504 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); | 3513 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); |
3505 options->write_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, WRITE_8, NULL); | 3514 options->write_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, WRITE_8, NULL); |
3506 options->gen.address_size = SZ_W; | 3515 options->gen.address_size = SZ_W; |
3507 options->gen.address_mask = 0xFFFF; | 3516 options->gen.address_mask = 0xFFFF; |
3517 options->gen.bus_cycles = 3; | |
3508 | 3518 |
3509 options->read_16 = code->cur; | 3519 options->read_16 = code->cur; |
3510 cycles(&options->gen, 3); | 3520 cycles(&options->gen, 3); |
3511 check_cycles(&options->gen); | 3521 check_cycles(&options->gen); |
3512 //TODO: figure out how to handle the extra wait state for word reads to bank area | 3522 //TODO: figure out how to handle the extra wait state for word reads to bank area |
3592 | 3602 |
3593 options->run = (z80_ctx_fun)code->cur; | 3603 options->run = (z80_ctx_fun)code->cur; |
3594 tmp_stack_off = code->stack_off; | 3604 tmp_stack_off = code->stack_off; |
3595 save_callee_save_regs(code); | 3605 save_callee_save_regs(code); |
3596 #ifdef X86_64 | 3606 #ifdef X86_64 |
3597 mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); | 3607 mov_rr(code, FIRST_ARG_REG, options->gen.context_reg, SZ_PTR); |
3598 #else | 3608 #else |
3599 mov_rdispr(code, RSP, 5 * sizeof(int32_t), options->gen.context_reg, SZ_PTR); | 3609 mov_rdispr(code, RSP, 5 * sizeof(int32_t), options->gen.context_reg, SZ_PTR); |
3600 #endif | 3610 #endif |
3601 call(code, options->load_context_scratch); | 3611 call(code, options->load_context_scratch); |
3602 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); | 3612 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); |