Added more FPU opcodes (further improves performance of JIT FPU), improved makefile profiler options

This commit is contained in:
Dimitris Panokostas 2018-02-03 01:30:57 +01:00
parent f1bddd57a1
commit 1b7525ddc0
18 changed files with 1320 additions and 1054 deletions

View file

@ -26,7 +26,6 @@ ifeq ($(PLATFORM),rpi3)
CFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL1 CFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry
NAME = amiberry-rpi3-sdl1-dev NAME = amiberry-rpi3-sdl1-dev
else ifeq ($(PLATFORM),rpi2) else ifeq ($(PLATFORM),rpi2)
@ -34,14 +33,12 @@ else ifeq ($(PLATFORM),rpi2)
CFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL1 CFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry
NAME = amiberry-rpi2-sdl1-dev NAME = amiberry-rpi2-sdl1-dev
else ifeq ($(PLATFORM),rpi1) else ifeq ($(PLATFORM),rpi1)
CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp
CFLAGS += ${DISPMANX_FLAGS} -DUSE_SDL1 CFLAGS += ${DISPMANX_FLAGS} -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
PROFILER_PATH = /home/pi/projects/amiberry
NAME = amiberry-rpi1-sdl1-dev NAME = amiberry-rpi1-sdl1-dev
else ifeq ($(PLATFORM),xu4) else ifeq ($(PLATFORM),xu4)
@ -72,7 +69,6 @@ USE_SDL2 = 1
CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 ${DISPMANX_FLAGS} CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi3-sdl2-dispmanx-dev NAME = amiberry-rpi3-sdl2-dispmanx-dev
else ifeq ($(PLATFORM),rpi2-sdl2-dispmanx) else ifeq ($(PLATFORM),rpi2-sdl2-dispmanx)
@ -81,7 +77,6 @@ USE_SDL2 = 1
CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 ${DISPMANX_FLAGS} CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi2-sdl2-dispmanx-dev NAME = amiberry-rpi2-sdl2-dispmanx-dev
else ifeq ($(PLATFORM),rpi1-sdl2-dispmanx) else ifeq ($(PLATFORM),rpi1-sdl2-dispmanx)
@ -89,7 +84,6 @@ USE_SDL2 = 1
CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp
CFLAGS += -DUSE_SDL2 ${DISPMANX_FLAGS} CFLAGS += -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS} LDFLAGS += ${DISPMANX_LDFLAGS}
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi1-sdl2-dispmanx-dev NAME = amiberry-rpi1-sdl2-dispmanx-dev
# #
@ -100,7 +94,6 @@ USE_SDL2 = 1
CPU_FLAGS += -march=armv8-a -mtune=cortex-a53 -mfpu=neon-fp-armv8 CPU_FLAGS += -march=armv8-a -mtune=cortex-a53 -mfpu=neon-fp-armv8
CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi3-sdl2-dev NAME = amiberry-rpi3-sdl2-dev
else ifeq ($(PLATFORM),rpi2-sdl2) else ifeq ($(PLATFORM),rpi2-sdl2)
@ -108,14 +101,12 @@ USE_SDL2 = 1
CPU_FLAGS += -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 CPU_FLAGS += -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4
CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2 CFLAGS += -DARMV6T2 -DUSE_ARMNEON -DUSE_SDL2
HAVE_NEON = 1 HAVE_NEON = 1
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi2-sdl2-dev NAME = amiberry-rpi2-sdl2-dev
else ifeq ($(PLATFORM),rpi1-sdl2) else ifeq ($(PLATFORM),rpi1-sdl2)
USE_SDL2 = 1 USE_SDL2 = 1
CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp CPU_FLAGS += -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp
CFLAGS += -DUSE_SDL2 CFLAGS += -DUSE_SDL2
PROFILER_PATH = /home/pi/projects/amiberry/amiberry-sdl2-prof
NAME = amiberry-rpi1-sdl2-dev NAME = amiberry-rpi1-sdl2-dev
else ifeq ($(PLATFORM),pine64) else ifeq ($(PLATFORM),pine64)
@ -191,7 +182,7 @@ DEFS += `xml2-config --cflags`
DEFS += -DAMIBERRY -DARMV6_ASSEMBLY DEFS += -DAMIBERRY -DARMV6_ASSEMBLY
ifndef DEBUG ifndef DEBUG
CFLAGS += -std=gnu++14 -Ofast CFLAGS += -std=gnu++14 -Ofast -frename-registers
else else
CFLAGS += -std=gnu++14 -g -rdynamic -funwind-tables -mapcs-frame -DDEBUG -Wl,--export-dynamic CFLAGS += -std=gnu++14 -g -rdynamic -funwind-tables -mapcs-frame -DDEBUG -Wl,--export-dynamic
endif endif
@ -206,10 +197,13 @@ ifdef GCC_PROFILE
endif endif
ifdef GEN_PROFILE ifdef GEN_PROFILE
CFLAGS += -fprofile-generate=$(PROFILER_PATH) -fprofile-arcs -fvpt CFLAGS += -fprofile-generate -fprofile-arcs -fvpt
LDFLAGS += -lgcov
endif endif
ifdef USE_PROFILE ifdef USE_PROFILE
CFLAGS += -fprofile-use -fprofile-correction -fbranch-probabilities -fvpt CFLAGS += -fprofile-use -fprofile-correction -fbranch-probabilities -fvpt
LDFLAGS += -lgcov
endif endif
ifdef SANITIZE ifdef SANITIZE
@ -476,6 +470,9 @@ clean:
$(RM) $(PROG) $(PROG)-debug $(OBJS) $(ASMS) $(OBJS:%.o=%.d) $(RM) $(PROG) $(PROG)-debug $(OBJS) $(ASMS) $(OBJS:%.o=%.d)
$(MAKE) -C src/guisan clean $(MAKE) -C src/guisan clean
cleanprofile:
$(RM) $(OBJS:%.o=%.gcda)
delasm: delasm:
$(RM) $(ASMS) $(RM) $(ASMS)

View file

@ -184,6 +184,11 @@ static void fpp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *w
*wrd2 = 0; *wrd2 = 0;
*wrd3 = 0; *wrd3 = 0;
return; return;
} else if (fpp_is_nan(fpd)) {
*wrd1 = 0x7fff0000;
*wrd2 = 0xffffffff;
*wrd3 = 0xffffffff;
return;
} }
if (v < 0) { if (v < 0) {
*wrd1 = 0x80000000; *wrd1 = 0x80000000;

View file

@ -60,7 +60,8 @@ enum {
NATIVE_CC_F_UGT = 16 + 10, NATIVE_CC_F_UGT = 16 + 10,
NATIVE_CC_F_UGE = 16 + 11, NATIVE_CC_F_UGE = 16 + 11,
NATIVE_CC_F_ULT = 16 + 12, NATIVE_CC_F_ULT = 16 + 12,
NATIVE_CC_F_ULE = 16 + 13 NATIVE_CC_F_ULE = 16 + 13,
NATIVE_CC_F_NEVER = 32
}; };

View file

@ -121,6 +121,7 @@ struct regstruct
uae_u32 address_space_mask; uae_u32 address_space_mask;
uae_s32 pissoff; uae_s32 pissoff;
uae_u8* natmem_offset;
}; };
extern struct regstruct regs; extern struct regstruct regs;

View file

@ -92,7 +92,7 @@ extern void __clear_cache (char*, char*);
#define STACK_OFFSET sizeof(void *) #define STACK_OFFSET sizeof(void *)
#define R_REGSTRUCT 11 #define R_REGSTRUCT 11
uae_s8 always_used[]={2,3,R_REGSTRUCT,12,-1}; // r12 is scratch register in C functions calls, I don't think it's save to use it here... uae_s8 always_used[]={2,3,R_REGSTRUCT,12,-1}; // r2, r3 and r12 are work register in emitted code
uae_u8 call_saved[]={0,0,0,0, 1,1,1,1, 1,1,1,1, 0,1,1,1}; uae_u8 call_saved[]={0,0,0,0, 1,1,1,1, 1,1,1,1, 0,1,1,1};
@ -1098,20 +1098,22 @@ LENDFUNC(NONE,NONE,2,compemu_raw_endblock_pc_isconst,(IMM cycles, IMM v))
* FPU stuff * * FPU stuff *
*************************************************************************/ *************************************************************************/
#ifdef USE_JIT_FPU
LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
{ {
VMOV64_rr(d, s); VMOV64_dd(d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
LOWFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s)) LOWFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s))
{ {
if(mem >= (uae_u32) &regs && mem < (uae_u32) &regs + 1020 && ((mem - (uae_u32) &regs) & 0x3) == 0) { if(mem >= (uae_u32) &regs && mem < (uae_u32) &regs + 1020 && ((mem - (uae_u32) &regs) & 0x3) == 0) {
VSTR64(s, R_REGSTRUCT, (mem - (uae_u32) &regs)); VSTR64_dRi(s, R_REGSTRUCT, (mem - (uae_u32) &regs));
} else { } else {
MOVW_ri16(REG_WORK1, mem); MOVW_ri16(REG_WORK1, mem);
MOVT_ri16(REG_WORK1, mem >> 16); MOVT_ri16(REG_WORK1, mem >> 16);
VSTR64(s, REG_WORK1, 0); VSTR64_dRi(s, REG_WORK1, 0);
} }
} }
LENDFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s)) LENDFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s))
@ -1120,69 +1122,69 @@ LENDFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s))
LOWFUNC(NONE,READ,2,compemu_raw_fmov_rm,(FW d, MEMR mem)) LOWFUNC(NONE,READ,2,compemu_raw_fmov_rm,(FW d, MEMR mem))
{ {
if(mem >= (uae_u32) &regs && mem < (uae_u32) &regs + 1020 && ((mem - (uae_u32) &regs) & 0x3) == 0) { if(mem >= (uae_u32) &regs && mem < (uae_u32) &regs + 1020 && ((mem - (uae_u32) &regs) & 0x3) == 0) {
VLDR64(d, R_REGSTRUCT, (mem - (uae_u32) &regs)); VLDR64_dRi(d, R_REGSTRUCT, (mem - (uae_u32) &regs));
} else { } else {
MOVW_ri16(REG_WORK1, mem); MOVW_ri16(REG_WORK1, mem);
MOVT_ri16(REG_WORK1, mem >> 16); MOVT_ri16(REG_WORK1, mem >> 16);
VLDR64(d, REG_WORK1, 0); VLDR64_dRi(d, REG_WORK1, 0);
} }
} }
LENDFUNC(NONE,READ,2,compemu_raw_fmov_rm,(FW d, MEMW mem)) LENDFUNC(NONE,READ,2,compemu_raw_fmov_rm,(FW d, MEMW mem))
LOWFUNC(NONE,NONE,2,raw_fmov_l_rr,(FW d, RR4 s)) LOWFUNC(NONE,NONE,2,raw_fmov_l_rr,(FW d, RR4 s))
{ {
VMOVi_from_ARM(SCRATCH_F64_1, s); VMOVi_from_ARM_dr(SCRATCH_F64_1, s, 0);
VCVT_64_from_i(d, SCRATCH_F32_1); VCVTIto64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_l_rr,(FW d, RR4 s)) LENDFUNC(NONE,NONE,2,raw_fmov_l_rr,(FW d, RR4 s))
LOWFUNC(NONE,NONE,2,raw_fmov_s_rr,(FW d, RR4 s)) LOWFUNC(NONE,NONE,2,raw_fmov_s_rr,(FW d, RR4 s))
{ {
VMOV32_from_ARM(SCRATCH_F32_1, s); VMOV32_sr(SCRATCH_F32_1, s);
VCVT_32_to_64(d, SCRATCH_F32_1); VCVT32to64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_s_rr,(FW d, RR4 s)) LENDFUNC(NONE,NONE,2,raw_fmov_s_rr,(FW d, RR4 s))
LOWFUNC(NONE,NONE,2,raw_fmov_w_rr,(FW d, RR2 s)) LOWFUNC(NONE,NONE,2,raw_fmov_w_rr,(FW d, RR2 s))
{ {
SIGN_EXTEND_16_REG_2_REG(REG_WORK1, s); SIGN_EXTEND_16_REG_2_REG(REG_WORK1, s);
VMOVi_from_ARM(SCRATCH_F64_1, REG_WORK1); VMOVi_from_ARM_dr(SCRATCH_F64_1, REG_WORK1, 0);
VCVT_64_from_i(d, SCRATCH_F32_1); VCVTIto64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_w_rr,(FW d, RR2 s)) LENDFUNC(NONE,NONE,2,raw_fmov_w_rr,(FW d, RR2 s))
LOWFUNC(NONE,NONE,2,raw_fmov_b_rr,(FW d, RR1 s)) LOWFUNC(NONE,NONE,2,raw_fmov_b_rr,(FW d, RR1 s))
{ {
SIGN_EXTEND_8_REG_2_REG(REG_WORK1, s); SIGN_EXTEND_8_REG_2_REG(REG_WORK1, s);
VMOVi_from_ARM(SCRATCH_F64_1, REG_WORK1); VMOVi_from_ARM_dr(SCRATCH_F64_1, REG_WORK1, 0);
VCVT_64_from_i(d, SCRATCH_F32_1); VCVTIto64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_b_rr,(FW d, RR1 s)) LENDFUNC(NONE,NONE,2,raw_fmov_b_rr,(FW d, RR1 s))
LOWFUNC(NONE,NONE,2,raw_fmov_d_rrr,(FW d, RR4 s1, RR4 s2)) LOWFUNC(NONE,NONE,2,raw_fmov_d_rrr,(FW d, RR4 s1, RR4 s2))
{ {
VMOV64_from_ARM(d, s1, s2); VMOV64_drr(d, s1, s2);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_d_rrr,(FW d, RR4 s1, RR4 s2)) LENDFUNC(NONE,NONE,2,raw_fmov_d_rrr,(FW d, RR4 s1, RR4 s2))
LOWFUNC(NONE,NONE,2,raw_fmov_to_l_rr,(W4 d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmov_to_l_rr,(W4 d, FR s))
{ {
VCVTR_64_to_i(SCRATCH_F32_1, s); VCVTR64toI_sd(SCRATCH_F32_1, s);
VMOVi_to_ARM(d, SCRATCH_F64_1); VMOV32_rs(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_to_l_rr,(W4 d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmov_to_l_rr,(W4 d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmov_to_s_rr,(W4 d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmov_to_s_rr,(W4 d, FR s))
{ {
VCVT_64_to_32(SCRATCH_F32_1, s); VCVT64to32_sd(SCRATCH_F32_1, s);
VMOV32_to_ARM(d, SCRATCH_F32_1); VMOV32_rs(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmov_to_s_rr,(W4 d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmov_to_s_rr,(W4 d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s))
{ {
VCVTR_64_to_i(SCRATCH_F32_1, s); VCVTR64toI_sd(SCRATCH_F32_1, s);
VMOVi_to_ARM(REG_WORK1, SCRATCH_F64_1); VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
SSAT_rir(REG_WORK1, 15, REG_WORK1); SSAT_rir(REG_WORK1, 15, REG_WORK1);
BFI_rrii(d, REG_WORK1, 0, 15); BFI_rrii(d, REG_WORK1, 0, 15);
} }
@ -1190,8 +1192,8 @@ LENDFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s))
{ {
VCVTR_64_to_i(SCRATCH_F32_1, s); VCVTR64toI_sd(SCRATCH_F32_1, s);
VMOVi_to_ARM(REG_WORK1, SCRATCH_F64_1); VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
SSAT_rir(REG_WORK1, 7, REG_WORK1); SSAT_rir(REG_WORK1, 7, REG_WORK1);
BFI_rrii(d, REG_WORK1, 0, 7); BFI_rrii(d, REG_WORK1, 0, 7);
} }
@ -1199,27 +1201,26 @@ LENDFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s))
LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_0,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_0,(FW r))
{ {
VMOV64_i(r, 0x7, 0x0); // load imm #1 into reg VMOV_I64_dimmI(r, 0x00); // load imm #0 into reg
VSUB64(r, r, r);
} }
LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_0,(FW r)) LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_0,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_1,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_1,(FW r))
{ {
VMOV64_i(r, 0x7, 0x0); // load imm #1 into reg VMOV_F64_dimmF(r, 0x70); // load imm #1 into reg
} }
LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_1,(FW r)) LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_1,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r))
{ {
VMOV64_i(r, 0x2, 0x4); // load imm #10 into reg VMOV_F64_dimmF(r, 0x24); // load imm #10 into reg
} }
LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r)) LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_100,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_d_ri_100,(FW r))
{ {
VMOV64_i(r, 0x2, 0x4); // load imm #10 into reg VMOV_F64_dimmF(r, 0x24); // load imm #10 into reg
VMUL64(r, r, r); VMUL64_ddd(r, r, r);
} }
LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r)) LENDFUNC(NONE,NONE,1,raw_fmov_d_ri_10,(FW r))
@ -1227,7 +1228,7 @@ LOWFUNC(NONE,READ,2,raw_fmov_d_rm,(FW r, MEMR m))
{ {
MOVW_ri16(REG_WORK1, m); MOVW_ri16(REG_WORK1, m);
MOVT_ri16(REG_WORK1, m >> 16); MOVT_ri16(REG_WORK1, m >> 16);
VLDR64(r, REG_WORK1, 0); VLDR64_dRi(r, REG_WORK1, 0);
} }
LENDFUNC(NONE,READ,2,raw_fmov_d_rm,(FW r, MEMR m)) LENDFUNC(NONE,READ,2,raw_fmov_d_rm,(FW r, MEMR m))
@ -1235,137 +1236,137 @@ LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
{ {
MOVW_ri16(REG_WORK1, m); MOVW_ri16(REG_WORK1, m);
MOVT_ri16(REG_WORK1, m >> 16); MOVT_ri16(REG_WORK1, m >> 16);
VLDR32(SCRATCH_F32_1, REG_WORK1, 0); VLDR32_sRi(SCRATCH_F32_1, REG_WORK1, 0);
VCVT_32_to_64(r, SCRATCH_F32_1); VCVT32to64_ds(r, SCRATCH_F32_1);
} }
LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m)) LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
LOWFUNC(NONE,NONE,3,raw_fmov_to_d_rrr,(W4 d1, W4 d2, FR s)) LOWFUNC(NONE,NONE,3,raw_fmov_to_d_rrr,(W4 d1, W4 d2, FR s))
{ {
VMOV64_to_ARM(d1, d2, s); VMOV64_rrd(d1, d2, s);
} }
LENDFUNC(NONE,NONE,3,raw_fmov_to_d_rrr,(W4 d1, W4 d2, FR s)) LENDFUNC(NONE,NONE,3,raw_fmov_to_d_rrr,(W4 d1, W4 d2, FR s))
LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
{ {
VSQRT64(d, s); VSQRT64_dd(d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
{ {
VABS64(d, s); VABS64_dd(d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
{ {
VNEG64(d, s); VNEG64_dd(d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
{ {
VDIV64(d, d, s); VDIV64_ddd(d, d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
{ {
VADD64(d, d, s); VADD64_ddd(d, d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
{ {
VMUL64(d, d, s); VMUL64_ddd(d, d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
{ {
VSUB64(d, d, s); VSUB64_ddd(d, d, s);
} }
LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
{ {
VCVTR_64_to_i(SCRATCH_F32_1, s); VCVTR64toI_sd(SCRATCH_F32_1, s);
VCVT_64_from_i(d, SCRATCH_F32_1); VCVTIto64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_frndintz_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frndintz_rr,(FW d, FR s))
{ {
VCVT_64_to_i(SCRATCH_F32_1, s); VCVT64toI_sd(SCRATCH_F32_1, s);
VCVT_64_from_i(d, SCRATCH_F32_1); VCVTIto64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_frndintz_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_frndintz_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmod_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmod_rr,(FRW d, FR s))
{ {
VDIV64(SCRATCH_F64_2, d, s); VDIV64_ddd(SCRATCH_F64_2, d, s);
VCVT_64_to_i(SCRATCH_F32_1, SCRATCH_F64_2); VCVT64toI_sd(SCRATCH_F32_1, SCRATCH_F64_2);
VCVT_64_from_i(SCRATCH_F64_2, SCRATCH_F32_1); VCVTIto64_ds(SCRATCH_F64_2, SCRATCH_F32_1);
VMUL64(SCRATCH_F64_1, SCRATCH_F64_2, s); VMUL64_ddd(SCRATCH_F64_1, SCRATCH_F64_2, s);
VSUB64(d, d, SCRATCH_F64_1); VSUB64_ddd(d, d, SCRATCH_F64_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmod_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmod_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsgldiv_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsgldiv_rr,(FRW d, FR s))
{ {
VCVT_64_to_32(SCRATCH_F32_1, d); VCVT64to32_sd(SCRATCH_F32_1, d);
VCVT_64_to_32(SCRATCH_F32_2, s); VCVT64to32_sd(SCRATCH_F32_2, s);
VDIV32(SCRATCH_F32_1, SCRATCH_F32_1, SCRATCH_F32_2); VDIV32_sss(SCRATCH_F32_1, SCRATCH_F32_1, SCRATCH_F32_2);
VCVT_32_to_64(d, SCRATCH_F32_1); VCVT32to64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fsgldiv_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fsgldiv_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r)) LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
{ {
VCVT_64_to_32(SCRATCH_F32_1, r); VCVT64to32_sd(SCRATCH_F32_1, r);
VCVT_32_to_64(r, SCRATCH_F32_1); VCVT32to64_ds(r, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r)) LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
{ {
VMRS(REG_WORK1); VMRS_r(REG_WORK1);
BIC_rri(REG_WORK2, REG_WORK1, 0x00c00000); BIC_rri(REG_WORK2, REG_WORK1, 0x00c00000);
VMSR(REG_WORK2); VMSR_r(REG_WORK2);
VDIV64(SCRATCH_F64_2, d, s); VDIV64_ddd(SCRATCH_F64_2, d, s);
VCVTR_64_to_i(SCRATCH_F32_1, SCRATCH_F64_2); VCVTR64toI_sd(SCRATCH_F32_1, SCRATCH_F64_2);
VCVT_64_from_i(SCRATCH_F64_2, SCRATCH_F32_1); VCVTIto64_ds(SCRATCH_F64_2, SCRATCH_F32_1);
VMUL64(SCRATCH_F64_1, SCRATCH_F64_2, s); VMUL64_ddd(SCRATCH_F64_1, SCRATCH_F64_2, s);
VSUB64(d, d, SCRATCH_F64_1); VSUB64_ddd(d, d, SCRATCH_F64_1);
VMRS(REG_WORK2); VMRS_r(REG_WORK2);
UBFX_rrii(REG_WORK1, REG_WORK1, 22, 2); UBFX_rrii(REG_WORK1, REG_WORK1, 22, 2);
BFI_rrii(REG_WORK2, REG_WORK1, 22, 2); BFI_rrii(REG_WORK2, REG_WORK1, 22, 2);
VMSR(REG_WORK2); VMSR_r(REG_WORK2);
} }
LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsglmul_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsglmul_rr,(FRW d, FR s))
{ {
VCVT_64_to_32(SCRATCH_F32_1, d); VCVT64to32_sd(SCRATCH_F32_1, d);
VCVT_64_to_32(SCRATCH_F32_2, s); VCVT64to32_sd(SCRATCH_F32_2, s);
VMUL32(SCRATCH_F32_1, SCRATCH_F32_1, SCRATCH_F32_2); VMUL32_sss(SCRATCH_F32_1, SCRATCH_F32_1, SCRATCH_F32_2);
VCVT_32_to_64(d, SCRATCH_F32_1); VCVT32to64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fsglmul_rr,(FRW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fsglmul_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmovs_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmovs_rr,(FW d, FR s))
{ {
VCVT_64_to_32(SCRATCH_F32_1, s); VCVT64to32_sd(SCRATCH_F32_1, s);
VCVT_32_to_64(d, SCRATCH_F32_1); VCVT32to64_ds(d, SCRATCH_F32_1);
} }
LENDFUNC(NONE,NONE,2,raw_fmovs_rr,(FW d, FR s)) LENDFUNC(NONE,NONE,2,raw_fmovs_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,3,raw_ffunc_rr,(double (*func)(double), FW d, FR s)) LOWFUNC(NONE,NONE,3,raw_ffunc_rr,(double (*func)(double), FW d, FR s))
{ {
VMOV64_rr(0, s); VMOV64_dd(0, s);
MOVW_ri16(REG_WORK1, (uae_u32)func); MOVW_ri16(REG_WORK1, (uae_u32)func);
MOVT_ri16(REG_WORK1, ((uae_u32)func) >> 16); MOVT_ri16(REG_WORK1, ((uae_u32)func) >> 16);
@ -1374,7 +1375,7 @@ LOWFUNC(NONE,NONE,3,raw_ffunc_rr,(double (*func)(double), FW d, FR s))
BLX_r(REG_WORK1); BLX_r(REG_WORK1);
POP(RLR_INDEX); POP(RLR_INDEX);
VMOV64_rr(d, 0); VMOV64_dd(d, 0);
} }
LENDFUNC(NONE,NONE,3,raw_ffunc_rr,(double (*func)(double), FW d, FR s)) LENDFUNC(NONE,NONE,3,raw_ffunc_rr,(double (*func)(double), FW d, FR s))
@ -1383,12 +1384,12 @@ LOWFUNC(NONE,NONE,3,raw_fpowx_rr,(uae_u32 x, FW d, FR s))
double (*func)(double,double) = pow; double (*func)(double,double) = pow;
if(x == 2) { if(x == 2) {
VMOV64_i(0, 0x0, 0x0); // load imm #2 into first reg VMOV_F64_dimmF(0, 0x00); // load imm #2 into first reg
} else { } else {
VMOV64_i(0, 0x2, 0x4); // load imm #10 into first reg VMOV_F64_dimmF(0, 0x24); // load imm #10 into first reg
} }
VMOV64_rr(1, s); VMOV64_dd(1, s);
MOVW_ri16(REG_WORK1, (uae_u32)func); MOVW_ri16(REG_WORK1, (uae_u32)func);
MOVT_ri16(REG_WORK1, ((uae_u32)func) >> 16); MOVT_ri16(REG_WORK1, ((uae_u32)func) >> 16);
@ -1397,12 +1398,227 @@ LOWFUNC(NONE,NONE,3,raw_fpowx_rr,(uae_u32 x, FW d, FR s))
BLX_r(REG_WORK1); BLX_r(REG_WORK1);
POP(RLR_INDEX); POP(RLR_INDEX);
VMOV64_rr(d, 0); VMOV64_dd(d, 0);
} }
LENDFUNC(NONE,NONE,3,raw_fpowx_rr,(uae_u32 x, FW d, FR s)) LENDFUNC(NONE,NONE,3,raw_fpowx_rr,(uae_u32 x, FW d, FR s))
LOWFUNC(NONE,WRITE,2,raw_fp_from_exten_mr,(RR4 adr, FR s))
{
uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
VMOVi_to_ARM_rd(REG_WORK2, s, 1); // get high part of double
VCMP64_d0(s);
VMRS_CPSR();
BEQ_i(22); // iszero
UBFX_rrii(REG_WORK3, REG_WORK2, 20, 11); // get exponent
MOVW_ri16(REG_WORK1, 2047);
CMP_rr(REG_WORK3, REG_WORK1);
BEQ_i(15); // isnan
MOVW_ri16(REG_WORK1, 15360); // diff of bias between double and long double
ADD_rrr(REG_WORK3, REG_WORK3, REG_WORK1); // exponent done
AND_rri(REG_WORK2, REG_WORK2, 0x80000000); // extract sign
ORR_rrrLSLi(REG_WORK3, REG_WORK2, REG_WORK3, 16); // merge sign and exponent
LDR_rRI(REG_WORK1, R_REGSTRUCT, offs);
ADD_rrr(REG_WORK1, adr, REG_WORK1);
REV_rr(REG_WORK3, REG_WORK3);
STR_rR(REG_WORK3, REG_WORK1); // write exponent
VSHL64_ddi(SCRATCH_F64_1, s, 11); // shift mantissa to correct position
VMOV64_rrd(REG_WORK3, REG_WORK2, SCRATCH_F64_1);
ORR_rri(REG_WORK2, REG_WORK2, 0x80000000); // insert explicit 1
REV_rr(REG_WORK2, REG_WORK2);
REV_rr(REG_WORK3, REG_WORK3);
STR_rRI(REG_WORK2, REG_WORK1, 4);
STR_rRI(REG_WORK3, REG_WORK1, 8);
B_i(10); // end_of_op
// isnan
MOVW_ri16(REG_WORK2, 0x7fff);
LSL_rri(REG_WORK2, REG_WORK2, 16);
MVN_ri(REG_WORK3, 0);
// iszero
CC_AND_rri(NATIVE_CC_EQ, REG_WORK2, REG_WORK2, 0x80000000); // extract sign
CC_MOV_ri(NATIVE_CC_EQ, REG_WORK3, 0);
LDR_rRI(REG_WORK1, R_REGSTRUCT, offs);
ADD_rrr(REG_WORK1, adr, REG_WORK1);
REV_rr(REG_WORK2, REG_WORK2);
STR_rR(REG_WORK2, REG_WORK1);
STR_rRI(REG_WORK3, REG_WORK1, 4);
STR_rRI(REG_WORK3, REG_WORK1, 8);
// end_of_op
}
LENDFUNC(NONE,WRITE,2,raw_fp_from_exten_mr,(RR4 adr, FR s))
LOWFUNC(NONE,READ,2,raw_fp_to_exten_rm,(FW d, RR4 adr))
{
uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
LDR_rRI(REG_WORK1, R_REGSTRUCT, offs);
ADD_rrr(REG_WORK1, adr, REG_WORK1);
LDR_rRI(REG_WORK2, REG_WORK1, 4);
LDR_rRI(REG_WORK3, REG_WORK1, 8);
REV_rr(REG_WORK2, REG_WORK2);
REV_rr(REG_WORK3, REG_WORK3);
BIC_rri(REG_WORK2, REG_WORK2, 0x80000000); // clear explicit 1
VMOV64_drr(d, REG_WORK3, REG_WORK2);
LDR_rR(REG_WORK2, REG_WORK1);
REV_rr(REG_WORK2, REG_WORK2);
LSR_rri(REG_WORK2, REG_WORK2, 16); // exponent now in lower half
MOVW_ri16(REG_WORK3, 0x7fff);
ANDS_rrr(REG_WORK3, REG_WORK3, REG_WORK2);
BNE_i(9); // not_zero
VCMP64_d0(d);
VMRS_CPSR();
BNE_i(6); // not zero
// zero
VMOV_I64_dimmI(d, 0x00);
TST_ri(REG_WORK2, 0x8000); // check sign
BEQ_i(12); // end_of_op
MOV_ri(REG_WORK2, 0x80000000);
MOV_ri(REG_WORK3, 0);
VMOV64_drr(d, REG_WORK3, REG_WORK2);
B_i(8); // end_of_op
// not_zero
MOVW_ri16(REG_WORK1, 15360); // diff of bias between double and long double
SUB_rrr(REG_WORK3, REG_WORK3, REG_WORK1); // exponent done, ToDo: check for carry -> result gets Inf in double
UBFX_rrii(REG_WORK2, REG_WORK2, 15, 1); // extract sign
BFI_rrii(REG_WORK3, REG_WORK2, 11, 1); // insert sign
VSHR64_ddi(d, d, 11); // shift mantissa to correct position
LSL_rri(REG_WORK3, REG_WORK3, 20);
VMOV_I64_dimmI(0, 0x00);
VMOVi_from_ARM_dr(0, REG_WORK3, 1);
VORR_ddd(d, d, 0);
// end_of_op
}
LENDFUNC(NONE,READ,2,raw_fp_from_exten_mr,(FW d, RR4 adr))
STATIC_INLINE void raw_fflags_into_flags(int r) STATIC_INLINE void raw_fflags_into_flags(int r)
{ {
VCMP64_0(r); VCMP64_d0(r);
VMRS(15); // special case: move flags from FPSCR to APSR_nzcv VMRS_CPSR();
} }
LOWFUNC(NONE,NONE,2,raw_fp_fscc_ri,(RW4 d, int cc))
{
switch (cc) {
case NATIVE_CC_F_NEVER:
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_NE: // Set if not equal
CC_BIC_rri(NATIVE_CC_EQ, d, d, 0xff); // do not set if equal
CC_ORR_rri(NATIVE_CC_NE, d, d, 0xff);
break;
case NATIVE_CC_EQ: // Set if equal
CC_BIC_rri(NATIVE_CC_NE, d, d, 0xff); // do not set if not equal
CC_ORR_rri(NATIVE_CC_EQ, d, d, 0xff);
break;
case NATIVE_CC_F_OGT: // Set if valid and greater than
BVS_i(2); // do not set if NaN
BLE_i(1); // do not set if less or equal
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_OGE: // Set if valid and greater or equal
BVS_i(2); // do not set if NaN
BCC_i(1); // do not set if carry cleared
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_OLT: // Set if vaild and less than
BVS_i(2); // do not set if NaN
BCS_i(1); // do not set if carry set
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_OLE: // Set if valid and less or equal
BVS_i(2); // do not set if NaN
BGT_i(1); // do not set if greater than
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_OGL: // Set if valid and greator or less
BVS_i(2); // do not set if NaN
BEQ_i(1); // do not set if equal
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_OR: // Set if valid
CC_BIC_rri(NATIVE_CC_VS, d, d, 0xff); // do not set if NaN
CC_ORR_rri(NATIVE_CC_VC, d, d, 0xff);
break;
case NATIVE_CC_F_UN: // Set if NAN
CC_BIC_rri(NATIVE_CC_VC, d, d, 0xff); // do not set if valid
CC_ORR_rri(NATIVE_CC_VS, d, d, 0xff);
break;
case NATIVE_CC_F_UEQ: // Set if NAN or equal
BVS_i(0); // set if NaN
BNE_i(1); // do not set if greater or less
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_UGT: // Set if NAN or greater than
BVS_i(0); // set if NaN
BLS_i(1); // do not set if lower or same
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_UGE: // Set if NAN or greater or equal
BVS_i(0); // set if NaN
BMI_i(1); // do not set if lower
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_ULT: // Set if NAN or less than
BVS_i(0); // set if NaN
BGE_i(1); // do not set if greater or equal
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
case NATIVE_CC_F_ULE: // Set if NAN or less or equal
BVS_i(0); // set if NaN
BGT_i(1); // do not set if greater
ORR_rri(d, d, 0xff);
B_i(0);
BIC_rri(d, d, 0xff);
break;
}
}
LENDFUNC(NONE,NONE,2,raw_fp_fscc_ri,(RW4 d, int cc))
#endif // USE_JIT_FPU

View file

@ -1317,6 +1317,9 @@ enum {
#define CC_SXTAH_rrr(cc,Rd,Rn,Rm) _W(((cc) << 28) | (0x6b << 20) | (Rn << 16) | ((Rd) << 12) | (0x7 << 4) | SHIFT_REG(Rm)) #define CC_SXTAH_rrr(cc,Rd,Rn,Rm) _W(((cc) << 28) | (0x6b << 20) | (Rn << 16) | ((Rd) << 12) | (0x7 << 4) | SHIFT_REG(Rm))
#define SXTAH_rrr(Rd,Rn,Rm) CC_SXTAH_rrr(NATIVE_CC_AL,Rd,Rn,Rm) #define SXTAH_rrr(Rd,Rn,Rm) CC_SXTAH_rrr(NATIVE_CC_AL,Rd,Rn,Rm)
#define CC_STM_Ri(cc,Rn,i) _W(((cc) << 28) | (0x8 << 24) | (0x8 << 20) | ((Rn) << 16) | i)
#define STM_Ri(Rn,i) CC_STM_Ri(NATIVE_CC_AL,Rn,i)
// ARMv6T2 // ARMv6T2
#ifdef ARMV6T2 #ifdef ARMV6T2
@ -1343,7 +1346,7 @@ enum {
// Floatingpoint // Floatingpoint
#define FADR_ADD(offs) ((1 << 23) | (offs) >> 2) #define FADR_ADD(offs) ((1 << 23) | (offs) >> 2)
#define FADR_SUB(offs) ((0 << 23) | (offs) >> 2) #define FADR_SUB(offs) ((0 << 23) | (offs) >> 2)
#define FIMM8(offs) (offs >= 0 ? FADR_ADD(offs) : FADR_SUB(-offs)) #define FOFFSET8(offs) (offs >= 0 ? FADR_ADD(offs) : FADR_SUB(-offs))
#define MAKE_Dd(Dd) (((Dd & 0x10) << 18) | ((Dd & 0x0f) << 12)) #define MAKE_Dd(Dd) (((Dd & 0x10) << 18) | ((Dd & 0x0f) << 12))
#define MAKE_Dm(Dm) (((Dm & 0x10) << 1) | ((Dm & 0x0f) << 0)) #define MAKE_Dm(Dm) (((Dm & 0x10) << 1) | ((Dm & 0x0f) << 0))
@ -1353,133 +1356,131 @@ enum {
#define MAKE_Sn(Sn) (((Sn & 0x01) << 7) | ((Sn & 0x1e) << 15)) #define MAKE_Sn(Sn) (((Sn & 0x01) << 7) | ((Sn & 0x1e) << 15))
#define CC_VLDR64(cc,Dd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x1 << 20) | (Rn << 16) | (0xb << 8) | FIMM8(offs) | MAKE_Dd(Dd)) #define CC_VLDR64_dRi(cc,Dd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x1 << 20) | (Rn << 16) | (0xb << 8) | FOFFSET8(offs) | MAKE_Dd(Dd))
#define VLDR64(Dd,Rn,offs) CC_VLDR64(NATIVE_CC_AL,Dd,Rn,offs) #define VLDR64_dRi(Dd,Rn,offs) CC_VLDR64_dRi(NATIVE_CC_AL,Dd,Rn,offs)
#define CC_VLDR32(cc,Sd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x1 << 20) | (Rn << 16) | (0xa << 8) | FIMM8(offs) | MAKE_Sd(Sd)) #define CC_VLDR32_sRi(cc,Sd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x1 << 20) | (Rn << 16) | (0xa << 8) | FOFFSET8(offs) | MAKE_Sd(Sd))
#define VLDR32(Sd,Rn,offs) CC_VLDR32(NATIVE_CC_AL,Sd,Rn,offs) #define VLDR32_sRi(Sd,Rn,offs) CC_VLDR32_sRi(NATIVE_CC_AL,Sd,Rn,offs)
#define CC_VSTR64(cc,Dd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x0 << 20) | (Rn << 16) | (0xb << 8) | FIMM8(offs) | MAKE_Dd(Dd)) #define CC_VSTR64_dRi(cc,Dd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x0 << 20) | (Rn << 16) | (0xb << 8) | FOFFSET8(offs) | MAKE_Dd(Dd))
#define VSTR64(Dd,Rn,offs) CC_VSTR64(NATIVE_CC_AL,Dd,Rn,offs) #define VSTR64_dRi(Dd,Rn,offs) CC_VSTR64_dRi(NATIVE_CC_AL,Dd,Rn,offs)
#define CC_VSTR32(cc,Dd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x0 << 20) | (Rn << 16) | (0xa << 8) | FIMM8(offs) | MAKE_Dd(Dd)) #define CC_VSTR32_sRi(cc,Sd,Rn,offs) _W(((cc) << 28) | (0xd << 24) | (0x0 << 20) | (Rn << 16) | (0xa << 8) | FOFFSET8(offs) | MAKE_Sd(Sd))
#define VSTR32(Dd,Rn,offs) CC_VSTR32(NATIVE_CC_AL,Dd,Rn,offs) #define VSTR32_sRi(Sd,Rn,offs) CC_VSTR32_sRi(NATIVE_CC_AL,Sd,Rn,offs)
#define CC_VMOV64_rr(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VMOV64_dd(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm))
#define VMOV64_rr(Dd,Dm) CC_VMOV64_rr(NATIVE_CC_AL,Dd,Dm) #define VMOV64_dd(Dd,Dm) CC_VMOV64_dd(NATIVE_CC_AL,Dd,Dm)
#define CC_VMOV32_rr(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VMOV32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VMOV32_rr(Sd,Sm) CC_VMOV32_rr(NATIVE_CC_AL,Sd,Sm) #define VMOV32_ss(Sd,Sm) CC_VMOV32_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VMOV32_to_ARM(cc,Rt,Sn) _W(((cc) << 28) | (0xe << 24) | (0x1 << 20) | (Rt << 12) | (0xa << 8) | (0x1 << 4) | MAKE_Sn(Sn)) #define CC_VMOV32_rs(cc,Rt,Sn) _W(((cc) << 28) | (0xe << 24) | (0x1 << 20) | (Rt << 12) | (0xa << 8) | (0x1 << 4) | MAKE_Sn(Sn))
#define VMOV32_to_ARM(Rt,Sn) CC_VMOV32_to_ARM(NATIVE_CC_AL,Rt,Sn) #define VMOV32_rs(Rt,Sn) CC_VMOV32_rs(NATIVE_CC_AL,Rt,Sn)
#define CC_VMOV32_from_ARM(cc,Sn,Rt) _W(((cc) << 28) | (0xe << 24) | (0x0 << 20) | (Rt << 12) | (0xa << 8) | (0x1 << 4) | MAKE_Sn(Sn)) #define CC_VMOV32_sr(cc,Sn,Rt) _W(((cc) << 28) | (0xe << 24) | (0x0 << 20) | (Rt << 12) | (0xa << 8) | (0x1 << 4) | MAKE_Sn(Sn))
#define VMOV32_from_ARM(Sn,Rt) CC_VMOV32_from_ARM(NATIVE_CC_AL,Sn,Rt) #define VMOV32_sr(Sn,Rt) CC_VMOV32_sr(NATIVE_CC_AL,Sn,Rt)
#define CC_VMOVi_from_ARM(cc,Dn,Rt) _W(((cc) << 28) | (0xe << 24) | (0x0 << 20) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dn(Dn)) #define CC_VMOVi_from_ARM_dr(cc,Dn,Rt,x) _W(((cc) << 28) | (0xe << 24) | (0x0 << 20) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | ((x) << 21) | MAKE_Dn(Dn))
#define VMOVi_from_ARM(Dn,Rt) CC_VMOVi_from_ARM(NATIVE_CC_AL,Dn,Rt) #define VMOVi_from_ARM_dr(Dn,Rt,x) CC_VMOVi_from_ARM_dr(NATIVE_CC_AL,Dn,Rt,x)
#define CC_VMOVi_to_ARM(cc,Rt,Dn) _W(((cc) << 28) | (0xe << 24) | (0x1 << 20) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dn(Dn)) #define CC_VMOVi_to_ARM_rd(cc,Rt,Dn,x) _W(((cc) << 28) | (0xe << 24) | (0x1 << 20) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | ((x) << 21) | MAKE_Dn(Dn))
#define VMOVi_to_ARM(Rt,Dn) CC_VMOVi_to_ARM(NATIVE_CC_AL,Rt,Dn) #define VMOVi_to_ARM_rd(Rt,Dn,x) CC_VMOVi_to_ARM_rd(NATIVE_CC_AL,Rt,Dn,x)
#define CC_VMOV64_to_ARM(cc,Rt,Rt2,Dm) _W(((cc) << 28) | (0xc << 24) | (0x5 << 20) | (Rt2 << 16) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dm(Dm)) #define CC_VMOV64_rrd(cc,Rt,Rt2,Dm) _W(((cc) << 28) | (0xc << 24) | (0x5 << 20) | (Rt2 << 16) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dm(Dm))
#define VMOV64_to_ARM(Rt,Rt2,Dm) CC_VMOV64_to_ARM(NATIVE_CC_AL,Rt,Rt2,Dm) #define VMOV64_rrd(Rt,Rt2,Dm) CC_VMOV64_rrd(NATIVE_CC_AL,Rt,Rt2,Dm)
#define CC_VMOV64_from_ARM(cc,Dm,Rt,Rt2) _W(((cc) << 28) | (0xc << 24) | (0x4 << 20) | (Rt2 << 16) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dm(Dm)) #define CC_VMOV64_drr(cc,Dm,Rt,Rt2) _W(((cc) << 28) | (0xc << 24) | (0x4 << 20) | (Rt2 << 16) | (Rt << 12) | (0xb << 8) | (0x1 << 4) | MAKE_Dm(Dm))
#define VMOV64_from_ARM(Dm,Rt,Rt2) CC_VMOV64_from_ARM(NATIVE_CC_AL,Dm,Rt,Rt2) #define VMOV64_drr(Dm,Rt,Rt2) CC_VMOV64_drr(NATIVE_CC_AL,Dm,Rt,Rt2)
#define CC_VCVT_64_to_32(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x7 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm)) #define CC_VCVT64to32_sd(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x7 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm))
#define VCVT_64_to_32(Sd,Dm) CC_VCVT_64_to_32(NATIVE_CC_AL,Sd,Dm) #define VCVT64to32_sd(Sd,Dm) CC_VCVT64to32_sd(NATIVE_CC_AL,Sd,Dm)
#define CC_VCVT_32_to_64(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x7 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm)) #define CC_VCVT32to64_ds(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x7 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm))
#define VCVT_32_to_64(Dd,Sm) CC_VCVT_32_to_64(NATIVE_CC_AL,Dd,Sm) #define VCVT32to64_ds(Dd,Sm) CC_VCVT32to64_ds(NATIVE_CC_AL,Dd,Sm)
#define CC_VCVTR_64_to_i(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xb << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm)) #define CC_VCVTR64toI_sd(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xb << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm))
#define VCVTR_64_to_i(Sd,Dm) CC_VCVTR_64_to_i(NATIVE_CC_AL,Sd,Dm) #define VCVTR64toI_sd(Sd,Dm) CC_VCVTR64toI_sd(NATIVE_CC_AL,Sd,Dm)
#define CC_VCVTR_32_to_i(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VCVTR32toI_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VCVTR_32_to_i(Sd,Sm) CC_VCVTR_32_to_i(NATIVE_CC_AL,Sd,Sm) #define VCVTR32toI_ss(Sd,Sm) CC_VCVTR32toI_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VCVT_64_to_i(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xb << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm)) #define CC_VCVT64toI_sd(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xb << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm))
#define VCVT_64_to_i(Sd,Dm) CC_VCVT_64_to_i(NATIVE_CC_AL,Sd,Dm) #define VCVT64toI_sd(Sd,Dm) CC_VCVT64toI_sd(NATIVE_CC_AL,Sd,Dm)
#define CC_VCVT_32_to_i(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VCVT32toI_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VCVT_32_to_i(Sd,Sm) CC_VCVT_32_to_i(NATIVE_CC_AL,Sd,Sm) #define VCVT32toI_ss(Sd,Sm) CC_VCVT32toI_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VCVT_64_from_i(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm)) #define CC_VCVTIto64_ds(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm))
#define VCVT_64_from_i(Dd,Sm) CC_VCVT_64_from_i(NATIVE_CC_AL,Dd,Sm) #define VCVTIto64_ds(Dd,Sm) CC_VCVTIto64_ds(NATIVE_CC_AL,Dd,Sm)
#define CC_VCVT_32_from_i(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VCVTIto32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VCVT_32_from_i(Sd,Sm) CC_VCVT_32_from_i(NATIVE_CC_AL,Dd,Sm) #define VCVTIto32_ss(Sd,Sm) CC_VCVTIto32_ss(NATIVE_CC_AL,Dd,Sm)
#define CC_VMOV_rr64(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VADD64_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm))
#define VMOV_rr64(Dd,Dm) CC_VMOV_rr64(NATIVE_CC_AL,Dd,Dm) #define VADD64_ddd(Dd,Dn,Dm) CC_VADD64_ddd(NATIVE_CC_AL,Dd,Dn,Dm)
#define CC_VMOV_rr32(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VADD32_sss(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm))
#define VMOV_rr32(Sd,Sm) CC_VMOV_rr32(NATIVE_CC_AL,Sd,Sm) #define VADD32_sss(Sd,Sn,Sm) CC_VADD32_sss(NATIVE_CC_AL,Sd,Sn,Sm)
#define CC_VADD64(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #define CC_VSUB64_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm))
#define VADD64(Dd,Dn,Dm) CC_VADD64(NATIVE_CC_AL,Dd,Dn,Dm) #define VSUB64_ddd(Dd,Dn,Dm) CC_VSUB64_ddd(NATIVE_CC_AL,Dd,Dn,Dm)
#define CC_VADD32(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm)) #define CC_VSUB32_sss(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm))
#define VADD32(Sd,Sn,Sm) CC_VADD32(NATIVE_CC_AL,Sd,Sn,Sm) #define VSUB32_sss(Sd,Sn,Sm) CC_VSUB32_sss(NATIVE_CC_AL,Sd,Sn,Sm)
#define CC_VSUB64(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #define CC_VMUL64_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x2 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm))
#define VSUB64(Dd,Dn,Dm) CC_VSUB64(NATIVE_CC_AL,Dd,Dn,Dm) #define VMUL64_ddd(Dd,Dn,Dm) CC_VMUL64_ddd(NATIVE_CC_AL,Dd,Dn,Dm)
#define CC_VSUB32(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm)) #define CC_VMUL32_sss(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x2 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm))
#define VSUB32(Sd,Sn,Sm) CC_VSUB32(NATIVE_CC_AL,Sd,Sn,Sm) #define VMUL32_sss(Sd,Sn,Sm) CC_VMUL32_sss(NATIVE_CC_AL,Sd,Sn,Sm)
#define CC_VMUL64(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x2 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #define CC_VDIV64_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x8 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm))
#define VMUL64(Dd,Dn,Dm) CC_VMUL64(NATIVE_CC_AL,Dd,Dn,Dm) #define VDIV64_ddd(Dd,Dn,Dm) CC_VDIV64_ddd(NATIVE_CC_AL,Dd,Dn,Dm)
#define CC_VMUL32(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x2 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm)) #define CC_VDIV32_sss(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x8 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm))
#define VMUL32(Sd,Sn,Sm) CC_VMUL32(NATIVE_CC_AL,Sd,Sn,Sm) #define VDIV32_sss(Sd,Sn,Sm) CC_VDIV32_sss(NATIVE_CC_AL,Sd,Sn,Sm)
#define CC_VDIV64(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x8 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #define CC_VABS64_dd(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm))
#define VDIV64(Dd,Dn,Dm) CC_VDIV64(NATIVE_CC_AL,Dd,Dn,Dm) #define VABS64_dd(Dd,Dm) CC_VABS64_dd(NATIVE_CC_AL,Dd,Dm)
#define CC_VDIV32(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x8 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm)) #define CC_VABS32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VDIV32(Sd,Sn,Sm) CC_VDIV32(NATIVE_CC_AL,Sd,Sn,Sm) #define VABS32_ss(Sd,Sm) CC_VABS32_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VABS64(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VNEG64_dd(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm))
#define VABS64(Dd,Dm) CC_VABS64(NATIVE_CC_AL,Dd,Dm) #define VNEG64_dd(Dd,Dm) CC_VNEG64_dd(NATIVE_CC_AL,Dd,Dm)
#define CC_VABS32(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VNEG32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VABS32(Sd,Sm) CC_VABS32(NATIVE_CC_AL,Sd,Sm) #define VNEG32_ss(Sd,Sm) CC_VNEG32_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VNEG64(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VSQRT64_dd(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm))
#define VNEG64(Dd,Dm) CC_VNEG64(NATIVE_CC_AL,Dd,Dm) #define VSQRT64_dd(Dd,Dm) CC_VSQRT64_dd(NATIVE_CC_AL,Dd,Dm)
#define CC_VNEG32(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xa << 8) | (0x4 << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VSQRT32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VNEG32(Sd,Sm) CC_VNEG32(NATIVE_CC_AL,Sd,Sm) #define VSQRT32_ss(Sd,Sm) CC_VSQRT32_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VSQRT64(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VCMP64_dd(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x4 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm))
#define VSQRT64(Dd,Dm) CC_VSQRT64(NATIVE_CC_AL,Dd,Dm) #define VCMP64_dd(Dd,Dm) CC_VCMP64_dd(NATIVE_CC_AL,Dd,Dm)
#define CC_VSQRT32(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x1 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define CC_VCMP32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x4 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VSQRT32(Sd,Sm) CC_VSQRT32(NATIVE_CC_AL,Sd,Sm) #define VCMP32_ss(Sd,Sm) CC_VCMP32_ss(NATIVE_CC_AL,Sd,Sm)
#define CC_VCMP64(cc,Dd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x4 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm)) #define CC_VCMP64_d0(cc,Dd) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x5 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd))
#define VCMP64(Dd,Dm) CC_VCMP64(NATIVE_CC_AL,Dd,Dm) #define VCMP64_d0(Dd) CC_VCMP64_d0(NATIVE_CC_AL,Dd)
#define CC_VCMP32(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x4 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm))
#define VCMP32(Sd,Sm) CC_VCMP32(NATIVE_CC_AL,Sd,Sm)
#define CC_VCMP64_0(cc,Dd) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x5 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd)) #define CC_VMRS_r(cc,Rt) _W(((cc) << 28) | (0xe << 24) | (0xf << 20) | (0x1 << 16) | (Rt << 12) | (0xa << 8) | (0x1 << 4))
#define VCMP64_0(Dd) CC_VCMP64_0(NATIVE_CC_AL,Dd) #define VMRS_r(Rt) CC_VMRS_r(NATIVE_CC_AL,Rt)
#define VMRS_CPSR() VMRS_r(15)
#define CC_VTST64(cc,Dd) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x5 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd)) #define CC_VMSR_r(cc,Rt) _W(((cc) << 28) | (0xe << 24) | (0xe << 20) | (0x1 << 16) | (Rt << 12) | (0xa << 8) | (0x1 << 4))
#define VTST64(Dd) CC_VTST64(NATIVE_CC_AL,Dd) #define VMSR_r(Rt) CC_VMSR_r(NATIVE_CC_AL,Rt)
#define CC_VTST32(cc,Sd) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x5 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd))
#define VTST32(Sd) CC_VTST32(NATIVE_CC_AL,Sd)
#define CC_VMRS(cc,Rt) _W(((cc) << 28) | (0xe << 24) | (0xf << 20) | (0x1 << 16) | (Rt << 12) | (0xa << 8) | (0x1 << 4)) // Immediate values for VBIC, VMOV (I32), VMVN (I32) and VORR
#define VMRS(Rt) CC_VMRS(NATIVE_CC_AL,Rt) #define FIMMVAL(imm) (((imm & 0x80) << 17) | ((imm & 0x70) << 12) | ((imm & 0x0f) << 0))
#define FIMM32(imm) ((imm & 0xffffff00) == 0 ? (FIMMVAL(imm >> 0) | (0x0 << 8)) : \
(imm & 0xffff00ff) == 0 ? (FIMMVAL(imm >> 8) | (0x1 << 8)) : \
(imm & 0xff00ffff) == 0 ? (FIMMVAL(imm >> 16) | (0x2 << 8)) : \
(FIMMVAL(imm >> 24) | (0x3 << 8))
#define CC_VMSR(cc,Rt) _W(((cc) << 28) | (0xe << 24) | (0xe << 20) | (0x1 << 16) | (Rt << 12) | (0xa << 8) | (0x1 << 4)) // VMOV I64: each bit of imm defines the value for an entire byte
#define VMSR(Rt) CC_VMSR(NATIVE_CC_AL,Rt) // imm <abcdefgh> -> aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
#define VMOV_I64_dimmI(Dd,imm) _W((0xf << 28) | (0x2 << 24) | (0x8 << 20) | (0x0 << 16) | (0xe << 8) | (0x3 << 4) | MAKE_Dd(Dd) | FIMMVAL(imm))
#define CC_VMOV64_i(cc,Dd,imm4H,imm4L) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (imm4H << 16) | (0xb << 8) | (imm4L) | MAKE_Dd(Dd)) // VMOV F64: imm <abcdefgh> -> aBbbbbbb bbcdefgh 00000000 00000000 00000000 00000000 00000000 00000000 (B = not b)
#define VMOV64_i(Dd,imm4H,imm4L) CC_VMOV64_i(NATIVE_CC_AL,Dd,imm4H,imm4L) #define FIMMF64(imm) (((imm & 0xf0) << 12) | ((imm & 0x0f) << 0))
#define CC_VMOV_F64_dimmF(cc,Dd,imm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xb << 8) | MAKE_Dd(Dd) | FIMMF64(imm))
#define VMOV_F64_dimmF(Dd,imm) CC_VMOV_F64_dimmF(NATIVE_CC_AL,Dd,imm)
// Floatingpoint used by non FPU JIT // VMOV F32: imm <abcdefgh> -> aBbbbbbc defgh000 00000000 00000000 (B = not b)
#define CC_VMOV_sr(cc,Sd,Rn) _W(((cc) << 28) | (0x70 << 21) | (0 << 20) | (Sd << 16) | (Rn << 12) | (0x0a << 8) | (0x10)) #define CC_VMOV_F32_si(cc,Sd,imm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xa << 8) | MAKE_Sd(Sd) | FIMMF64(imm))
#define VMOV_sr(Sd,Rn) CC_VMOV_sr(NATIVE_CC_AL,Sd,Rn) #define VMOV_F32_si(Sd,imm) CC_VMOV_F32_si(NATIVE_CC_AL,sd,imm)
#define CC_VMOV_rs(cc,Rd,Sn) _W(((cc) << 28) | (0x70 << 21) | (1 << 20) | (Sn << 16) | (Rd << 12) | (0x0a << 8) | (0x10)) // Immediate value for shift
#define VMOV_rs(Rd,Sn) CC_VMOV_rs(NATIVE_CC_AL,Rd,Sn) #define FIMM6(imm) ((imm) << 16)
#define VSHL64_ddi(Dd,Dm,imm) _W((0xf << 28) | (0x2 << 24) | (0x8 << 20) | (0x5 << 8) | (0x9 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm) | FIMM6(imm))
#define CC_VCVT_f64_u32(cc,Dd,Sn) _W(((cc) << 28) | (0x1d << 23) | (0x7 << 19) | (0x0 << 16) | (Dd << 12) | (0xb << 8) | (0x4 << 4) | (Sn)) #define VSHR64_ddi(Dd,Dm,imm) _W((0xf << 28) | (0x3 << 24) | (0x8 << 20) | (0x0 << 8) | (0x9 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm) | FIMM6(64-imm))
#define VCVT_f64_u32(Dd,Sn) CC_VCVT_f64_u32(NATIVE_CC_AL,Dd,Sn)
#define CC_VCVT_u32_f64(cc,Sd,Dn) _W(((cc) << 28) | (0x1d << 23) | (0x7 << 19) | (0x4 << 16) | (Sd << 12) | (0xb << 8) | (0xc << 4) | (Dn))
#define VCVT_u32_f64(Sd,Dn) CC_VCVT_u32_f64(NATIVE_CC_AL,Sd,Dn)
#define CC_VDIV_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0x1d << 23) | (0x0 << 20) | (Dn << 16) | (Dd << 12) | (0xb << 8) | (0x0 << 4) | (Dm))
#define VDIV_ddd(Dd,Dn,Dm) CC_VDIV_ddd(NATIVE_CC_AL,Dd,Dn,Dm)
#define VORR_ddd(Dd,Dn,Dm) _W((0xf << 28) | (0x2 << 24) | (0x2 << 20) | (0x1 << 8) | (0x1 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dn) | MAKE_Dm(Dm))
#endif /* ARM_RTASM_H */ #endif /* ARM_RTASM_H */

View file

@ -90,7 +90,7 @@ typedef union {
#define BYTES_PER_INST 10240 /* paranoid ;-) */ #define BYTES_PER_INST 10240 /* paranoid ;-) */
#if defined(CPU_arm) #if defined(CPU_arm)
#define LONGEST_68K_INST 128 /* The number of bytes the longest possible #define LONGEST_68K_INST 256 /* The number of bytes the longest possible
68k instruction takes */ 68k instruction takes */
#else #else
#define LONGEST_68K_INST 16 /* The number of bytes the longest possible #define LONGEST_68K_INST 16 /* The number of bytes the longest possible
@ -127,7 +127,7 @@ typedef union {
#else #else
#define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ #define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */
#endif #endif
#define N_FREGS 16 // We use 16 regs: 0 - FP_RESULT, 1-3 - SCRATCH, 4-7 - ???, 8-15 - Amiga regs FP0-FP7 #define N_FREGS 16 // We use 10 regs: 6 - FP_RESULT, 7 - SCRATCH, 8-15 - Amiga regs FP0-FP7
/* Functions exposed to newcpu, or to what was moved from newcpu.c to /* Functions exposed to newcpu, or to what was moved from newcpu.c to
@ -140,8 +140,6 @@ extern void set_target(uae_u8* t);
extern void freescratch(void); extern void freescratch(void);
extern void build_comp(void); extern void build_comp(void);
extern void set_cache_state(int enabled); extern void set_cache_state(int enabled);
extern int get_cache_state(void);
extern uae_u32 get_jitted_size(void);
#ifdef JIT #ifdef JIT
extern void flush_icache(int n); extern void flush_icache(int n);
extern void flush_icache_hard(int n); extern void flush_icache_hard(int n);
@ -166,7 +164,7 @@ extern uae_u8* comp_pc_p;
extern void* pushall_call_handler; extern void* pushall_call_handler;
#define VREGS 32 #define VREGS 32
#define VFREGS 16 #define VFREGS 10
#define INMEM 1 #define INMEM 1
#define CLEAN 2 #define CLEAN 2
@ -224,8 +222,6 @@ STATIC_INLINE int end_block(uae_u16 opcode)
#define FP_RESULT 8 #define FP_RESULT 8
#define FS1 9 #define FS1 9
#define FS2 10
#define FS3 11
#define SCRATCH_F64_1 1 #define SCRATCH_F64_1 1
#define SCRATCH_F64_2 2 #define SCRATCH_F64_2 2
@ -326,6 +322,7 @@ extern void readlong(int address, int dest, int tmp);
extern void writebyte(int address, int source, int tmp); extern void writebyte(int address, int source, int tmp);
extern void writeword(int address, int source, int tmp); extern void writeword(int address, int source, int tmp);
extern void writelong(int address, int source, int tmp); extern void writelong(int address, int source, int tmp);
extern void writeword_clobber(int address, int source, int tmp);
extern void writelong_clobber(int address, int source, int tmp); extern void writelong_clobber(int address, int source, int tmp);
extern void get_n_addr(int address, int dest, int tmp); extern void get_n_addr(int address, int dest, int tmp);
extern void get_n_addr_jmp(int address, int dest, int tmp); extern void get_n_addr_jmp(int address, int dest, int tmp);

View file

@ -34,7 +34,7 @@ STATIC_INLINE int comp_fp_get (uae_u32 opcode, uae_u16 extra, int treg)
int mode = (opcode >> 3) & 7; int mode = (opcode >> 3) & 7;
int size = (extra >> 10) & 7; int size = (extra >> 10) & 7;
if ((size == 2 && (mode != 7 || reg != 4)) || size == 3 || size == 7) /* 2 = long double, 3 = packed decimal, 7 is not defined */ if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */
return -1; return -1;
switch (mode) { switch (mode) {
case 0: /* Dn */ case 0: /* Dn */
@ -180,6 +180,9 @@ STATIC_INLINE int comp_fp_get (uae_u32 opcode, uae_u16 extra, int treg)
readlong (S1, S2, S3); readlong (S1, S2, S3);
fmov_s_rr (treg, S2); fmov_s_rr (treg, S2);
return 1; return 1;
case 2: /* Long Double */
fp_to_exten_rm (treg, S1);
return 0;
case 4: /* Word */ case 4: /* Word */
readword (S1, S2, S3); readword (S1, S2, S3);
fmov_w_rr (treg, S2); fmov_w_rr (treg, S2);
@ -208,7 +211,7 @@ STATIC_INLINE int comp_fp_put (uae_u32 opcode, uae_u16 extra)
int mode = (opcode >> 3) & 7; int mode = (opcode >> 3) & 7;
int size = (extra >> 10) & 7; int size = (extra >> 10) & 7;
if (size == 2 || size == 3 || size == 7) /* 2 = long double, 3 = packed decimal, 7 is not defined */ if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */
return -1; return -1;
switch (mode) { switch (mode) {
case 0: /* Dn */ case 0: /* Dn */
@ -281,10 +284,13 @@ STATIC_INLINE int comp_fp_put (uae_u32 opcode, uae_u16 extra)
case 1: /* Single */ case 1: /* Single */
fmov_to_s_rr(S2, sreg); fmov_to_s_rr(S2, sreg);
writelong_clobber (S1, S2, S3); writelong_clobber (S1, S2, S3);
return 0;
case 2:/* Long Double */
fp_from_exten_mr (S1, sreg);
return 0; return 0;
case 4: /* Word */ case 4: /* Word */
fmov_to_w_rr(S2, sreg); fmov_to_w_rr(S2, sreg);
writeword (S1, S2, S3); writeword_clobber (S1, S2, S3);
return 0; return 0;
case 5: /* Double */ case 5: /* Double */
fmov_to_d_rrr(S2, S3, sreg); fmov_to_d_rrr(S2, S3, sreg);
@ -344,14 +350,45 @@ void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra)
void comp_fscc_opp (uae_u32 opcode, uae_u16 extra) void comp_fscc_opp (uae_u32 opcode, uae_u16 extra)
{ {
//printf("comp_fscc_opp() called (0x%04x, 0x%04x)\n", opcode, extra); int reg;
if (!currprefs.compfpu) { if (!currprefs.compfpu) {
FAIL (1); FAIL (1);
return; return;
} }
if (extra & 0x20) { /* only cc from 00 to 1f are defined */
FAIL (1); FAIL (1);
return; return;
}
if ((opcode & 0x38) != 0) { /* We can only do to integer register */
FAIL (1);
return;
}
fflags_into_flags ();
reg = (opcode & 7);
if (!(opcode & 0x38)) {
switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */
case 0: fp_fscc_ri(reg, NATIVE_CC_F_NEVER); break;
case 1: fp_fscc_ri(reg, NATIVE_CC_EQ); break;
case 2: fp_fscc_ri(reg, NATIVE_CC_F_OGT); break;
case 3: fp_fscc_ri(reg, NATIVE_CC_F_OGE); break;
case 4: fp_fscc_ri(reg, NATIVE_CC_F_OLT); break;
case 5: fp_fscc_ri(reg, NATIVE_CC_F_OLE); break;
case 6: fp_fscc_ri(reg, NATIVE_CC_F_OGL); break;
case 7: fp_fscc_ri(reg, NATIVE_CC_F_OR); break;
case 8: fp_fscc_ri(reg, NATIVE_CC_F_UN); break;
case 9: fp_fscc_ri(reg, NATIVE_CC_F_UEQ); break;
case 10: fp_fscc_ri(reg, NATIVE_CC_F_UGT); break;
case 11: fp_fscc_ri(reg, NATIVE_CC_F_UGE); break;
case 12: fp_fscc_ri(reg, NATIVE_CC_F_ULT); break;
case 13: fp_fscc_ri(reg, NATIVE_CC_F_ULE); break;
case 14: fp_fscc_ri(reg, NATIVE_CC_NE); break;
case 15: fp_fscc_ri(reg, NATIVE_CC_AL); break;
}
}
} }
void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc) void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc)
@ -519,7 +556,121 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
return; return;
case 6: case 6:
case 7: case 7:
{
uae_u32 list = 0;
int incr = 0;
if (extra & 0x2000) {
int ad;
/* FMOVEM FPP->memory */
switch ((extra >> 11) & 3) { /* Get out early if failure */
case 0:
case 2:
break;
case 1:
case 3:
default:
FAIL (1); FAIL (1);
return;
}
ad = comp_fp_adr (opcode);
if (ad < 0) {
m68k_setpc (m68k_getpc () - 4);
op_illg (opcode);
return;
}
switch ((extra >> 11) & 3) {
case 0: /* static pred */
list = extra & 0xff;
incr = -1;
break;
case 2: /* static postinc */
list = extra & 0xff;
incr = 1;
break;
case 1: /* dynamic pred */
case 3: /* dynamic postinc */
abort ();
}
if (incr < 0) { /* Predecrement */
for (reg = 7; reg >= 0; reg--) {
if (list & 0x80) {
sub_l_ri (ad, 12);
fp_from_exten_mr (ad, reg);
}
list <<= 1;
}
} else { /* Postincrement */
for (reg = 0; reg <= 7; reg++) {
if (list & 0x80) {
fp_from_exten_mr (ad, reg);
add_l_ri (ad, 12);
}
list <<= 1;
}
}
if ((opcode & 0x38) == 0x18)
mov_l_rr ((opcode & 7) + 8, ad);
if ((opcode & 0x38) == 0x20)
mov_l_rr ((opcode & 7) + 8, ad);
} else {
/* FMOVEM memory->FPP */
int ad;
switch ((extra >> 11) & 3) { /* Get out early if failure */
case 0:
case 2:
break;
case 1:
case 3:
default:
FAIL (1);
return;
}
ad = comp_fp_adr (opcode);
if (ad < 0) {
m68k_setpc (m68k_getpc () - 4);
op_illg (opcode);
return;
}
switch ((extra >> 11) & 3) {
case 0: /* static pred */
list = extra & 0xff;
incr = -1;
break;
case 2: /* static postinc */
list = extra & 0xff;
incr = 1;
break;
case 1: /* dynamic pred */
case 3: /* dynamic postinc */
abort ();
}
if (incr < 0) {
// not reached
for (reg = 7; reg >= 0; reg--) {
if (list & 0x80) {
sub_l_ri (ad, 12);
fp_to_exten_rm(reg, ad);
}
list <<= 1;
}
} else {
for (reg = 0; reg <= 7; reg++) {
if (list & 0x80) {
fp_to_exten_rm(reg, ad);
add_l_ri (ad, 12);
}
list <<= 1;
}
}
if ((opcode & 0x38) == 0x18)
mov_l_rr ((opcode & 7) + 8, ad);
if ((opcode & 0x38) == 0x20)
mov_l_rr ((opcode & 7) + 8, ad);
}
}
return; return;
case 2: /* from <EA> to FPx */ case 2: /* from <EA> to FPx */
dont_care_fflags (); dont_care_fflags ();
@ -722,11 +873,13 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
case 0x35: case 0x35:
case 0x36: case 0x36:
case 0x37: case 0x37:
if (dreg == (extra & 7)) FAIL (1);
ffunc_rr (sin, dreg, sreg); return;
else // if (dreg == (extra & 7))
fsincos_rr (dreg, extra & 7, sreg); // ffunc_rr (sin, dreg, sreg);
break; // else
// fsincos_rr (dreg, extra & 7, sreg);
// break;
case 0x38: /* FCMP */ case 0x38: /* FCMP */
fmov_rr (FP_RESULT, dreg); fmov_rr (FP_RESULT, dreg);
fsub_rr (FP_RESULT, sreg); fsub_rr (FP_RESULT, sreg);

View file

@ -491,6 +491,8 @@ STATIC_INLINE void emit_jmp_target(uae_u32 a) {
* FPU stuff * * FPU stuff *
*************************************************************************/ *************************************************************************/
#ifdef USE_JIT_FPU
MIDFUNC(1,f_forget_about,(FW r)) MIDFUNC(1,f_forget_about,(FW r))
{ {
if (f_isinreg(r)) if (f_isinreg(r))
@ -875,24 +877,26 @@ MIDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s))
} }
MENDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s)) MENDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s))
MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) //MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s))
{ //{
clobber_flags(); // clobber_flags();
prepare_for_call_1(); // prepare_for_call_1();
prepare_for_call_2(); // prepare_for_call_2();
//
s = f_readreg(s); /* s for source */ // s = f_readreg(s); /* s for source */
d = f_writereg(d); /* d for sine */ // d = f_writereg(d); /* d for sine */
c = f_writereg(c); /* c for cosine */ // c = f_writereg(c); /* c for cosine */
//
raw_ffunc_rr(cos, c, s); // // s may be FS1, so we need to save it before we call external func
raw_ffunc_rr(sin, d, s); //
// raw_ffunc_rr(cos, c, s);
f_unlock(s); // raw_ffunc_rr(sin, d, s);
f_unlock(d); //
f_unlock(c); // f_unlock(s);
} // f_unlock(d);
MENDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) // f_unlock(c);
//}
//MENDFUNC(3,fsincos_rr,(FW d, FW c, FR s))
MIDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s)) MIDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s))
{ {
@ -917,3 +921,37 @@ MIDFUNC(1,fflags_into_flags,())
fflags_into_flags_internal(); fflags_into_flags_internal();
} }
MENDFUNC(1,fflags_into_flags,()) MENDFUNC(1,fflags_into_flags,())
MIDFUNC(2,fp_from_exten_mr,(RR4 adr, FR s))
{
clobber_flags();
adr = readreg(adr, 4);
s = f_readreg(s);
raw_fp_from_exten_mr(adr, s);
f_unlock(s);
unlock2(adr);
}
MENDFUNC(2,fp_from_exten_mr,(RR4 adr, FR s))
MIDFUNC(2,fp_to_exten_rm,(FW d, RR4 adr))
{
clobber_flags();
adr = readreg(adr, 4);
d = f_writereg(d);
raw_fp_to_exten_rm(d, adr);
unlock2(adr);
f_unlock(d);
}
MENDFUNC(2,fp_to_exten_rm,(FW d, RR4 adr))
MIDFUNC(2,fp_fscc_ri,(RW4 d, int cc))
{
d = rmw(d, 4, 4);
raw_fp_fscc_ri(d, cc);
unlock2(d);
}
MENDFUNC(2,fp_fscc_ri,(RW4 d, int cc))
#endif // USE_JIT_FPU

View file

@ -108,3 +108,6 @@ DECLARE_MIDFUNC(ffunc_rr(double (*func)(double), FW d, FR s));
DECLARE_MIDFUNC(fsincos_rr(FW d, FW c, FR s)); DECLARE_MIDFUNC(fsincos_rr(FW d, FW c, FR s));
DECLARE_MIDFUNC(fpowx_rr(uae_u32 x, FW d, FR s)); DECLARE_MIDFUNC(fpowx_rr(uae_u32 x, FW d, FR s));
DECLARE_MIDFUNC(fflags_into_flags()); DECLARE_MIDFUNC(fflags_into_flags());
DECLARE_MIDFUNC(fp_from_exten_mr(RR4 adr, FR s));
DECLARE_MIDFUNC(fp_to_exten_rm(FW d, RR4 adr));
DECLARE_MIDFUNC(fp_fscc_ri(RW4, int cc));

View file

@ -1859,13 +1859,13 @@ MENDFUNC(2,jff_DBCC,(RR2 d, IMM cc))
s2 = readreg(s2, 4); s2 = readreg(s2, 4);
d = writereg(d, 4); d = writereg(d, 4);
VMOV_sr(0, s1); // move to s0 VMOV32_sr(0, s1); // move to s0
VMOV_sr(1, s2); // move to s1 VMOV32_sr(1, s2); // move to s1
VCVT_f64_u32(2, 0); // convert s0 to d2 (int to float) VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float)
VCVT_f64_u32(3, 1); // convert s1 to d3 (int to float) VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float)
VDIV_ddd(4, 2, 3); // d4 = d2 / d3 VDIV64_ddd(4, 2, 3); // d4 = d2 / d3
VCVT_u32_f64(0, 4); // convert d4 to s0 (float to int) VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int)
VMOV_rs(REG_WORK1, 0); // move from s0 VMOV32_rs(REG_WORK1, 0); // move from s0
LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows -> no result LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows -> no result
BNE_i(2); BNE_i(2);
@ -1887,13 +1887,13 @@ MIDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2))
s2 = readreg(s2, 4); s2 = readreg(s2, 4);
d = writereg(d, 4); d = writereg(d, 4);
VMOV_sr(0, s1); // move to s0 VMOV32_sr(0, s1); // move to s0
VMOV_sr(1, s2); // move to s1 VMOV32_sr(1, s2); // move to s1
VCVT_f64_u32(2, 0); // convert s0 to d2 (int to float) VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float)
VCVT_f64_u32(3, 1); // convert s1 to d3 (int to float) VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float)
VDIV_ddd(4, 2, 3); // d4 = d2 / d3 VDIV64_ddd(4, 2, 3); // d4 = d2 / d3
VCVT_u32_f64(0, 4); // convert d4 to s0 (float to int) VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int)
VMOV_rs(REG_WORK1, 0); // move from s0 VMOV32_rs(REG_WORK1, 0); // move from s0
LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows
BEQ_i(2); BEQ_i(2);
@ -2855,13 +2855,8 @@ MIDFUNC(2,jnf_MOVE16,(RR4 d, RR4 s))
BIC_rri(s, s, 0x0000000F); BIC_rri(s, s, 0x0000000F);
BIC_rri(d, d, 0x0000000F); BIC_rri(d, d, 0x0000000F);
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK1, NATMEM_OFFSETX); LDR_rRI(REG_WORK1, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK1, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK1, RPC_INDEX, offs);
#endif
ADD_rrr(s, s, REG_WORK1); ADD_rrr(s, s, REG_WORK1);
ADD_rrr(d, d, REG_WORK1); ADD_rrr(d, d, REG_WORK1);
@ -5115,13 +5110,8 @@ MENDFUNC(1,jff_TST_l,(RR4 s))
*/ */
MIDFUNC(2,jnf_MEM_WRITE_OFF_b,(RR4 adr, RR4 b)) MIDFUNC(2,jnf_MEM_WRITE_OFF_b,(RR4 adr, RR4 b))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
b = readreg(b, 4); b = readreg(b, 4);
@ -5135,13 +5125,8 @@ MENDFUNC(2,jnf_MEM_WRITE_OFF_b,(RR4 adr, RR4 b))
MIDFUNC(2,jnf_MEM_WRITE_OFF_w,(RR4 adr, RR4 w)) MIDFUNC(2,jnf_MEM_WRITE_OFF_w,(RR4 adr, RR4 w))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
w = readreg(w, 4); w = readreg(w, 4);
@ -5156,13 +5141,8 @@ MENDFUNC(2,jnf_MEM_WRITE_OFF_w,(RR4 adr, RR4 w))
MIDFUNC(2,jnf_MEM_WRITE_OFF_l,(RR4 adr, RR4 l)) MIDFUNC(2,jnf_MEM_WRITE_OFF_l,(RR4 adr, RR4 l))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
l = readreg(l, 4); l = readreg(l, 4);
@ -5178,13 +5158,8 @@ MENDFUNC(2,jnf_MEM_WRITE_OFF_l,(RR4 adr, RR4 l))
MIDFUNC(2,jnf_MEM_READ_OFF_b,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ_OFF_b,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5198,13 +5173,8 @@ MENDFUNC(2,jnf_MEM_READ_OFF_b,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_READ_OFF_w,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ_OFF_w,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5219,13 +5189,8 @@ MENDFUNC(2,jnf_MEM_READ_OFF_w,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_READ_OFF_l,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ_OFF_l,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5241,13 +5206,8 @@ MENDFUNC(2,jnf_MEM_READ_OFF_l,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_WRITE24_OFF_b,(RR4 adr, RR4 b)) MIDFUNC(2,jnf_MEM_WRITE24_OFF_b,(RR4 adr, RR4 b))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
b = readreg(b, 4); b = readreg(b, 4);
@ -5262,13 +5222,8 @@ MENDFUNC(2,jnf_MEM_WRITE24_OFF_b,(RR4 adr, RR4 b))
MIDFUNC(2,jnf_MEM_WRITE24_OFF_w,(RR4 adr, RR4 w)) MIDFUNC(2,jnf_MEM_WRITE24_OFF_w,(RR4 adr, RR4 w))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
w = readreg(w, 4); w = readreg(w, 4);
@ -5284,13 +5239,8 @@ MENDFUNC(2,jnf_MEM_WRITE24_OFF_w,(RR4 adr, RR4 w))
MIDFUNC(2,jnf_MEM_WRITE24_OFF_l,(RR4 adr, RR4 l)) MIDFUNC(2,jnf_MEM_WRITE24_OFF_l,(RR4 adr, RR4 l))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
l = readreg(l, 4); l = readreg(l, 4);
@ -5307,13 +5257,8 @@ MENDFUNC(2,jnf_MEM_WRITE24_OFF_l,(RR4 adr, RR4 l))
MIDFUNC(2,jnf_MEM_READ24_OFF_b,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ24_OFF_b,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5328,13 +5273,8 @@ MENDFUNC(2,jnf_MEM_READ24_OFF_b,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_READ24_OFF_w,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ24_OFF_w,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5350,13 +5290,8 @@ MENDFUNC(2,jnf_MEM_READ24_OFF_w,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_READ24_OFF_l,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_READ24_OFF_l,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5373,13 +5308,8 @@ MENDFUNC(2,jnf_MEM_READ24_OFF_l,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_GETADR_OFF,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_GETADR_OFF,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);
@ -5393,13 +5323,8 @@ MENDFUNC(2,jnf_MEM_GETADR_OFF,(W4 d, RR4 adr))
MIDFUNC(2,jnf_MEM_GETADR24_OFF,(W4 d, RR4 adr)) MIDFUNC(2,jnf_MEM_GETADR24_OFF,(W4 d, RR4 adr))
{ {
#ifdef ARMV6T2 uae_s32 offs = (uae_u32)&NATMEM_OFFSETX - (uae_u32) &regs;
MOVW_ri16(REG_WORK2, NATMEM_OFFSETX); LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
MOVT_ri16(REG_WORK2, NATMEM_OFFSETX >> 16);
#else
uae_s32 offs = get_data_natmem();
LDR_rRI(REG_WORK2, RPC_INDEX, offs);
#endif
adr = readreg(adr, 4); adr = readreg(adr, 4);
d = writereg(d, 4); d = writereg(d, 4);

View file

@ -81,7 +81,7 @@ static clock_t emul_end_time = 0;
#endif #endif
#ifdef PROFILE_UNTRANSLATED_INSNS #ifdef PROFILE_UNTRANSLATED_INSNS
static int untranslated_top_ten = 30; static int untranslated_top_ten = 20;
static uae_u32 raw_cputbl_count[65536] = { 0, }; static uae_u32 raw_cputbl_count[65536] = { 0, };
static uae_u16 opcode_nums[65536]; static uae_u16 opcode_nums[65536];
@ -92,7 +92,7 @@ static int untranslated_compfn(const void *e1, const void *e2)
} }
#endif #endif
#define NATMEM_OFFSETX (uae_u32)natmem_offset #define NATMEM_OFFSETX regs.natmem_offset
static compop_func *compfunctbl[65536]; static compop_func *compfunctbl[65536];
static compop_func *nfcompfunctbl[65536]; static compop_func *nfcompfunctbl[65536];
@ -735,8 +735,6 @@ static uae_u32 data_wasted = 0;
static uae_u32 data_buffers_used = 0; static uae_u32 data_buffers_used = 0;
#endif #endif
static uae_s32 data_natmem_pos = 0;
STATIC_INLINE void compemu_raw_branch(IMM d); STATIC_INLINE void compemu_raw_branch(IMM d);
STATIC_INLINE void data_check_end(uae_s32 n, uae_s32 codesize) STATIC_INLINE void data_check_end(uae_s32 n, uae_s32 codesize)
@ -753,8 +751,6 @@ STATIC_INLINE void data_check_end(uae_s32 n, uae_s32 codesize)
data_writepos = get_target_noopt(); data_writepos = get_target_noopt();
data_endpos = data_writepos + DATA_BUFFER_SIZE; data_endpos = data_writepos + DATA_BUFFER_SIZE;
set_target(get_target_noopt() + DATA_BUFFER_SIZE); set_target(get_target_noopt() + DATA_BUFFER_SIZE);
data_natmem_pos = 0;
} }
} }
@ -789,15 +785,6 @@ STATIC_INLINE uae_s32 get_data_offset(uae_s32 t)
return t - (uae_s32)get_target_noopt() - 8; return t - (uae_s32)get_target_noopt() - 8;
} }
STATIC_INLINE uae_s32 get_data_natmem(void)
{
if(data_natmem_pos == 0 || (uae_s32)get_target_noopt() - data_natmem_pos >= DATA_BUFFER_MAXOFFSET)
{
data_natmem_pos = data_long(NATMEM_OFFSETX, 4);
}
return get_data_offset(data_natmem_pos);
}
STATIC_INLINE void reset_data_buffer(void) STATIC_INLINE void reset_data_buffer(void)
{ {
data_writepos = 0; data_writepos = 0;
@ -1407,26 +1394,27 @@ STATIC_INLINE void f_disassociate(int r)
} }
static int f_alloc_reg(int r, int willclobber) static int f_alloc_reg(int r, int willclobber)
{ {
int bestreg; int bestreg;
if(r < 8) if(r < 8)
bestreg = r + 8; // map real Amiga reg to ARM VFP reg 8-15 bestreg = r + 8; // map real Amiga reg to ARM VFP reg 8-15 (call save)
else else if(r == FP_RESULT)
bestreg = r - 8; // map FP_RESULT, FS1, FS2 or FS3 to ARM VFP reg 0-3 bestreg = 6; // map FP_RESULT to ARM VFP reg 6
else // FS1
bestreg = 7; // map FS1 to ARM VFP reg 7
if (!willclobber) { if (!willclobber) {
if (live.fate[r].status == INMEM) { if (live.fate[r].status == INMEM) {
compemu_raw_fmov_rm(bestreg, (uintptr)live.fate[r].mem); compemu_raw_fmov_rm(bestreg, (uintptr)live.fate[r].mem);
live.fate[r].status=CLEAN; live.fate[r].status = CLEAN;
} }
} }
else { else {
live.fate[r].status = DIRTY; live.fate[r].status = DIRTY;
} }
live.fate[r].realreg=bestreg; live.fate[r].realreg = bestreg;
live.fat[bestreg].holds = r; live.fat[bestreg].holds = r;
live.fat[bestreg].nholds = 1; live.fat[bestreg].nholds = 1;
@ -1533,24 +1521,6 @@ static scratch_t scratch;
* Support functions exposed to newcpu * * Support functions exposed to newcpu *
********************************************************************/ ********************************************************************/
static void compiler_init(void)
{
static bool initialized = false;
if (initialized)
return;
initialized = true;
#ifdef PROFILE_UNTRANSLATED_INSNS
jit_log("<JIT compiler> : gather statistics on untranslated insns count");
#endif
#ifdef PROFILE_COMPILE_TIME
jit_log("<JIT compiler> : gather statistics on translation time");
emul_start_time = clock();
#endif
}
void compiler_exit(void) void compiler_exit(void)
{ {
#ifdef PROFILE_COMPILE_TIME #ifdef PROFILE_COMPILE_TIME
@ -1601,14 +1571,6 @@ void compiler_exit(void)
dp = table68k + opcode_nums[i]; dp = table68k + opcode_nums[i];
for (lookup = lookuptab; lookup->mnemo != (instrmnem)dp->mnemo; lookup++) for (lookup = lookuptab; lookup->mnemo != (instrmnem)dp->mnemo; lookup++)
; ;
if(strcmp(lookup->name, "FPP") == 0
|| strcmp(lookup->name, "FBcc") == 0
|| strcmp(lookup->name, "DIVS") == 0
|| strcmp(lookup->name, "DIVU") == 0
|| strcmp(lookup->name, "DIVL") == 0) {
untranslated_top_ten++; // Ignore this
}
else
jit_log("%03d: %04x %10u %s", i, opcode_nums[i], count, lookup->name); jit_log("%03d: %04x %10u %s", i, opcode_nums[i], count, lookup->name);
} }
#endif #endif
@ -1749,8 +1711,7 @@ void freescratch(void)
for (i = S1; i < VREGS; i++) for (i = S1; i < VREGS; i++)
forget_about(i); forget_about(i);
for (i = FS1; i <= FS3; i++) // only FS1-FS3 f_forget_about(FS1);
f_forget_about(i);
} }
/******************************************************************** /********************************************************************
@ -1784,9 +1745,10 @@ static void flush_all(void)
tomem(i); tomem(i);
} }
} }
for (i = FP_RESULT; i <= FS3; i++) // only FP_RESULT and FS1-FS3, FP0-FP7 are call save if (f_isinreg(FP_RESULT))
if (f_isinreg(i)) f_evict(FP_RESULT);
f_evict(i); if (f_isinreg(FS1))
f_evict(FS1);
} }
/* Make sure all registers that will get clobbered by a call are /* Make sure all registers that will get clobbered by a call are
@ -1808,7 +1770,7 @@ static void prepare_for_call_2(void)
free_nreg(i); free_nreg(i);
} }
for (i = 0; i < 4; i++) // only FP_RESULT and FS1-FS3, FP0-FP7 are call save for (i = 6; i <= 7; i++) // only FP_RESULT and FS1, FP0-FP7 are call save
if (live.fat[i].nholds > 0) if (live.fat[i].nholds > 0)
f_free_nreg(i); f_free_nreg(i);
@ -1915,6 +1877,14 @@ STATIC_INLINE void writemem_real_clobber(int address, int source, int size)
forget_about(source); forget_about(source);
} }
void writeword_clobber(int address, int source, int tmp)
{
if (special_mem & S_WRITE)
writemem_special(address, source, 16, 2, tmp);
else
writemem_real_clobber(address, source, 2);
}
void writelong_clobber(int address, int source, int tmp) void writelong_clobber(int address, int source, int tmp)
{ {
if (special_mem & S_WRITE) if (special_mem & S_WRITE)
@ -2084,18 +2054,6 @@ void set_cache_state(int enabled)
letit = enabled; letit = enabled;
} }
int get_cache_state(void)
{
return letit;
}
uae_u32 get_jitted_size(void)
{
if (compiled_code)
return current_compile_p - compiled_code;
return 0;
}
void alloc_cache(void) void alloc_cache(void)
{ {
if (compiled_code) { if (compiled_code) {

View file

@ -15,22 +15,21 @@
#include <SDL.h> #include <SDL.h>
uae_u8* natmem_offset = nullptr;
static uae_u32 natmem_size; static uae_u32 natmem_size;
uae_u32 max_z3fastmem; uae_u32 max_z3fastmem;
/* JIT can access few bytes outside of memory block of it executes code at the very end of memory block */ /* JIT can access few bytes outside of memory block of it executes code at the very end of memory block */
#define BARRIER 32 #define BARRIER 32
static uae_u8* additional_mem = (uae_u8*)MAP_FAILED; static uae_u8* additional_mem = (uae_u8*) MAP_FAILED;
#define ADDITIONAL_MEMSIZE ((128 + 16) * 1024 * 1024) #define ADDITIONAL_MEMSIZE (128 + 16) * 1024 * 1024
static uae_u8* a3000_mem = (uae_u8*)MAP_FAILED; static uae_u8* a3000_mem = (uae_u8*) MAP_FAILED;
static int a3000_totalsize = 0; static int a3000_totalsize = 0;
#define A3000MEM_START 0x08000000 #define A3000MEM_START 0x08000000
static unsigned int lastLowSize = 0; static int lastLowSize = 0;
static unsigned int lastHighSize = 0; static int lastHighSize = 0;
int z3base_adr = 0; int z3base_adr = 0;
@ -38,24 +37,24 @@ int z3base_adr = 0;
void free_AmigaMem(void) void free_AmigaMem(void)
{ {
if (natmem_offset != nullptr) if(regs.natmem_offset != 0)
{ {
#ifdef AMIBERRY #ifdef AMIBERRY
munmap(natmem_offset, natmem_size + BARRIER); munmap(regs.natmem_offset, natmem_size + BARRIER);
#else #else
free(natmem_offset); free(regs.natmem_offset);
#endif #endif
natmem_offset = nullptr; regs.natmem_offset = 0;
} }
if (additional_mem != MAP_FAILED) if(additional_mem != MAP_FAILED)
{ {
munmap(additional_mem, ADDITIONAL_MEMSIZE + BARRIER); munmap(additional_mem, ADDITIONAL_MEMSIZE + BARRIER);
additional_mem = (uae_u8*)MAP_FAILED; additional_mem = (uae_u8*) MAP_FAILED;
} }
if (a3000_mem != MAP_FAILED) if(a3000_mem != MAP_FAILED)
{ {
munmap(a3000_mem, a3000_totalsize); munmap(a3000_mem, a3000_totalsize);
a3000_mem = (uae_u8*)MAP_FAILED; a3000_mem = (uae_u8*) MAP_FAILED;
a3000_totalsize = 0; a3000_totalsize = 0;
} }
} }
@ -75,54 +74,51 @@ void alloc_AmigaMem(void)
natmem_size = 16 * 1024 * 1024; natmem_size = 16 * 1024 * 1024;
#ifdef AMIBERRY #ifdef AMIBERRY
// address returned by valloc() too high for later mmap() calls. Use mmap() also for first area. // address returned by valloc() too high for later mmap() calls. Use mmap() also for first area.
natmem_offset = (uae_u8*)mmap(reinterpret_cast<void *>(0x20000000), natmem_size + BARRIER, regs.natmem_offset = (uae_u8*) mmap((void *)0x20000000, natmem_size + BARRIER,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
#else #else
natmem_offset = (uae_u8*)valloc(natmem_size + BARRIER); regs.natmem_offset = (uae_u8*)valloc (natmem_size + BARRIER);
#endif #endif
max_z3fastmem = ADDITIONAL_MEMSIZE - (16 * 1024 * 1024); max_z3fastmem = ADDITIONAL_MEMSIZE - (16 * 1024 * 1024);
if (!natmem_offset) { if (!regs.natmem_offset) {
write_log("Can't allocate 16M of virtual address space!?\n"); write_log("Can't allocate 16M of virtual address space!?\n");
abort(); abort();
} }
// FIXME This part of code caused crash on Android devices additional_mem = (uae_u8*) mmap(regs.natmem_offset + Z3BASE_REAL, ADDITIONAL_MEMSIZE + BARRIER,
#ifndef ANDROID
additional_mem = (uae_u8*)mmap(natmem_offset + Z3BASE_REAL, ADDITIONAL_MEMSIZE + BARRIER,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (additional_mem != MAP_FAILED) if(additional_mem != MAP_FAILED)
{ {
// Allocation successful -> we can use natmem_offset for entire memory access at real address // Allocation successful -> we can use natmem_offset for entire memory access at real address
changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_REAL; changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_REAL;
z3base_adr = Z3BASE_REAL; z3base_adr = Z3BASE_REAL;
write_log("Allocated 16 MB for 24-bit area (0x%08x) and %d MB for Z3 and RTG at real address (0x%08x - 0x%08x)\n", write_log("Allocated 16 MB for 24-bit area (0x%08x) and %d MB for Z3 and RTG at real address (0x%08x - 0x%08x)\n",
natmem_offset, ADDITIONAL_MEMSIZE / (1024 * 1024), additional_mem, additional_mem + ADDITIONAL_MEMSIZE + BARRIER); regs.natmem_offset, ADDITIONAL_MEMSIZE / (1024 * 1024), additional_mem, additional_mem + ADDITIONAL_MEMSIZE + BARRIER);
set_expamem_z3_hack_mode(Z3MAPPING_REAL); set_expamem_z3_hack_mode(Z3MAPPING_REAL);
return; return;
} }
additional_mem = (uae_u8*)mmap(natmem_offset + Z3BASE_UAE, ADDITIONAL_MEMSIZE + BARRIER, additional_mem = (uae_u8*) mmap(regs.natmem_offset + Z3BASE_UAE, ADDITIONAL_MEMSIZE + BARRIER,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (additional_mem != MAP_FAILED) if(additional_mem != MAP_FAILED)
{ {
// Allocation successful -> we can use natmem_offset for entire memory access at fake address // Allocation successful -> we can use natmem_offset for entire memory access at fake address
changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_UAE; changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_UAE;
z3base_adr = Z3BASE_UAE; z3base_adr = Z3BASE_UAE;
write_log("Allocated 16 MB for 24-bit area (0x%08x) and %d MB for Z3 and RTG at fake address (0x%08x - 0x%08x)\n", write_log("Allocated 16 MB for 24-bit area (0x%08x) and %d MB for Z3 and RTG at fake address (0x%08x - 0x%08x)\n",
natmem_offset, ADDITIONAL_MEMSIZE / (1024 * 1024), additional_mem, additional_mem + ADDITIONAL_MEMSIZE + BARRIER); regs.natmem_offset, ADDITIONAL_MEMSIZE / (1024 * 1024), additional_mem, additional_mem + ADDITIONAL_MEMSIZE + BARRIER);
set_expamem_z3_hack_mode(Z3MAPPING_UAE); set_expamem_z3_hack_mode(Z3MAPPING_UAE);
return; return;
} }
#endif
#ifdef AMIBERRY #ifdef AMIBERRY
munmap(natmem_offset, natmem_size + BARRIER); munmap(regs.natmem_offset, natmem_size + BARRIER);
#else #else
free(natmem_offset); free(regs.natmem_offset);
#endif #endif
// Next attempt: allocate huge memory block for entire area // Next attempt: allocate huge memory block for entire area
natmem_size = ADDITIONAL_MEMSIZE + 256 * 1024 * 1024; natmem_size = ADDITIONAL_MEMSIZE + 256 * 1024 * 1024;
natmem_offset = (uae_u8*)valloc(natmem_size + BARRIER); regs.natmem_offset = (uae_u8*)valloc (natmem_size + BARRIER);
if (natmem_offset) if(regs.natmem_offset)
{ {
// Allocation successful // Allocation successful
changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_UAE; changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_UAE;
@ -133,9 +129,9 @@ void alloc_AmigaMem(void)
// No mem for Z3 or RTG at all // No mem for Z3 or RTG at all
natmem_size = 16 * 1024 * 1024; natmem_size = 16 * 1024 * 1024;
natmem_offset = (uae_u8*)valloc(natmem_size + BARRIER); regs.natmem_offset = (uae_u8*)valloc (natmem_size + BARRIER);
if (!natmem_offset) { if (!regs.natmem_offset) {
write_log("Can't allocate 16M of virtual address space!?\n"); write_log("Can't allocate 16M of virtual address space!?\n");
abort(); abort();
} }
@ -144,36 +140,36 @@ void alloc_AmigaMem(void)
z3base_adr = 0x00000000; z3base_adr = 0x00000000;
max_z3fastmem = 0; max_z3fastmem = 0;
write_log("Reserved: %p-%p (0x%08x %dM)\n", natmem_offset, (uae_u8*)natmem_offset + natmem_size, write_log("Reserved: %p-%p (0x%08x %dM)\n", regs.natmem_offset, (uae_u8*)regs.natmem_offset + natmem_size,
natmem_size, natmem_size >> 20); natmem_size, natmem_size >> 20);
} }
static bool HandleA3000Mem(unsigned int lowsize, unsigned int highsize) static bool HandleA3000Mem(int lowsize, int highsize)
{ {
auto result = true; bool result = true;
if (lowsize == lastLowSize && highsize == lastHighSize) if(lowsize == lastLowSize && highsize == lastHighSize)
return result; return result;
if (a3000_mem != MAP_FAILED) if(a3000_mem != MAP_FAILED)
{ {
write_log("HandleA3000Mem(): Free A3000 memory (0x%08x). %d MB.\n", a3000_mem, a3000_totalsize / (1024 * 1024)); write_log("HandleA3000Mem(): Free A3000 memory (0x%08x). %d MB.\n", a3000_mem, a3000_totalsize / (1024 * 1024));
munmap(a3000_mem, a3000_totalsize); munmap(a3000_mem, a3000_totalsize);
a3000_mem = (uae_u8*)MAP_FAILED; a3000_mem = (uae_u8*) MAP_FAILED;
a3000_totalsize = 0; a3000_totalsize = 0;
lastLowSize = 0; lastLowSize = 0;
lastHighSize = 0; lastHighSize = 0;
} }
if (lowsize + highsize > 0) if(lowsize + highsize > 0)
{ {
// Try to get memory for A3000 motherboard // Try to get memory for A3000 motherboard
write_log("Try to get A3000 memory at correct place (0x%08x). %d MB and %d MB.\n", A3000MEM_START, write_log("Try to get A3000 memory at correct place (0x%08x). %d MB and %d MB.\n", A3000MEM_START,
lowsize / (1024 * 1024), highsize / (1024 * 1024)); lowsize / (1024 * 1024), highsize / (1024 * 1024));
a3000_totalsize = lowsize + highsize; a3000_totalsize = lowsize + highsize;
a3000_mem = (uae_u8*)mmap(natmem_offset + (A3000MEM_START - lowsize), a3000_totalsize, a3000_mem = (uae_u8*) mmap(regs.natmem_offset + (A3000MEM_START - lowsize), a3000_totalsize,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (a3000_mem != MAP_FAILED) if(a3000_mem != MAP_FAILED)
{ {
lastLowSize = lowsize; lastLowSize = lowsize;
lastHighSize = highsize; lastHighSize = highsize;
@ -199,8 +195,8 @@ static bool A3000MemAvailable(void)
bool uae_mman_info(addrbank *ab, struct uae_mman_data *md) bool uae_mman_info(addrbank *ab, struct uae_mman_data *md)
{ {
auto got = false; bool got = false;
auto readonly = false; bool readonly = false;
uaecptr start; uaecptr start;
uae_u32 size = ab->reserved_size; uae_u32 size = ab->reserved_size;
uae_u32 readonlysize = size; uae_u32 readonlysize = size;
@ -211,173 +207,139 @@ bool uae_mman_info(addrbank *ab, struct uae_mman_data *md)
got = true; got = true;
if (expansion_get_autoconfig_by_address(&currprefs, ab->start) && !expansion_get_autoconfig_by_address(&currprefs, ab->start + size)) if (expansion_get_autoconfig_by_address(&currprefs, ab->start) && !expansion_get_autoconfig_by_address(&currprefs, ab->start + size))
barrier = true; barrier = true;
} } else if (!_tcscmp(ab->label, _T("*B"))) {
else if (!_tcscmp(ab->label, _T("*B"))) {
start = ab->start; start = ab->start;
got = true; got = true;
barrier = true; barrier = true;
} } else if (!_tcscmp(ab->label, _T("chip"))) {
else if (!_tcscmp(ab->label, _T("chip"))) {
start = 0; start = 0;
got = true; got = true;
if (!expansion_get_autoconfig_by_address(&currprefs, 0x00200000) && currprefs.chipmem_size == 2 * 1024 * 1024) if (!expansion_get_autoconfig_by_address(&currprefs, 0x00200000) && currprefs.chipmem_size == 2 * 1024 * 1024)
barrier = true; barrier = true;
if (currprefs.chipmem_size > 2 * 1024 * 1024) if (currprefs.chipmem_size > 2 * 1024 * 1024)
barrier = true; barrier = true;
} } else if (!_tcscmp(ab->label, _T("kick"))) {
else if (!_tcscmp(ab->label, _T("kick"))) {
start = 0xf80000; start = 0xf80000;
got = true; got = true;
barrier = true; barrier = true;
readonly = true; readonly = true;
} } else if (!_tcscmp(ab->label, _T("rom_a8"))) {
else if (!_tcscmp(ab->label, _T("rom_a8"))) {
start = 0xa80000; start = 0xa80000;
got = true; got = true;
readonly = true; readonly = true;
} } else if (!_tcscmp(ab->label, _T("rom_e0"))) {
else if (!_tcscmp(ab->label, _T("rom_e0"))) {
start = 0xe00000; start = 0xe00000;
got = true; got = true;
readonly = true; readonly = true;
} } else if (!_tcscmp(ab->label, _T("rom_f0"))) {
else if (!_tcscmp(ab->label, _T("rom_f0"))) {
start = 0xf00000; start = 0xf00000;
got = true; got = true;
readonly = true; readonly = true;
} } else if (!_tcscmp(ab->label, _T("rom_f0_ppc"))) {
else if (!_tcscmp(ab->label, _T("rom_f0_ppc"))) {
// this is flash and also contains IO // this is flash and also contains IO
start = 0xf00000; start = 0xf00000;
got = true; got = true;
readonly = false; readonly = false;
} } else if (!_tcscmp(ab->label, _T("rtarea"))) {
else if (!_tcscmp(ab->label, _T("rtarea"))) {
start = rtarea_base; start = rtarea_base;
got = true; got = true;
readonly = true; readonly = true;
readonlysize = RTAREA_TRAPS; readonlysize = RTAREA_TRAPS;
} } else if (!_tcscmp(ab->label, _T("ramsey_low"))) {
else if (!_tcscmp(ab->label, _T("ramsey_low"))) { if(ab->reserved_size != lastLowSize)
if (ab->reserved_size != lastLowSize)
HandleA3000Mem(ab->reserved_size, lastHighSize); HandleA3000Mem(ab->reserved_size, lastHighSize);
if (A3000MemAvailable()) { if(A3000MemAvailable()) {
start = a3000lmem_bank.start; start = a3000lmem_bank.start;
got = true; got = true;
} }
} } else if (!_tcscmp(ab->label, _T("csmk1_maprom"))) {
else if (!_tcscmp(ab->label, _T("csmk1_maprom"))) {
start = 0x07f80000; start = 0x07f80000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("25bitram"))) {
else if (!_tcscmp(ab->label, _T("25bitram"))) {
start = 0x01000000; start = 0x01000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("ramsey_high"))) {
else if (!_tcscmp(ab->label, _T("ramsey_high"))) { if(ab->reserved_size != lastHighSize)
if (ab->reserved_size != lastHighSize)
HandleA3000Mem(lastLowSize, ab->reserved_size); HandleA3000Mem(lastLowSize, ab->reserved_size);
if (A3000MemAvailable()) { if(A3000MemAvailable()) {
start = 0x08000000; start = 0x08000000;
got = true; got = true;
} }
} } else if (!_tcscmp(ab->label, _T("dkb"))) {
else if (!_tcscmp(ab->label, _T("dkb"))) {
start = 0x10000000; start = 0x10000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("fusionforty"))) {
else if (!_tcscmp(ab->label, _T("fusionforty"))) {
start = 0x11000000; start = 0x11000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("blizzard_40"))) {
else if (!_tcscmp(ab->label, _T("blizzard_40"))) {
start = 0x40000000; start = 0x40000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("blizzard_48"))) {
else if (!_tcscmp(ab->label, _T("blizzard_48"))) {
start = 0x48000000; start = 0x48000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("blizzard_68"))) {
else if (!_tcscmp(ab->label, _T("blizzard_68"))) {
start = 0x68000000; start = 0x68000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("blizzard_70"))) {
else if (!_tcscmp(ab->label, _T("blizzard_70"))) {
start = 0x70000000; start = 0x70000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("cyberstorm"))) {
else if (!_tcscmp(ab->label, _T("cyberstorm"))) {
start = 0x0c000000; start = 0x0c000000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("cyberstormmaprom"))) {
else if (!_tcscmp(ab->label, _T("cyberstormmaprom"))) {
start = 0xfff00000; start = 0xfff00000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("bogo"))) {
else if (!_tcscmp(ab->label, _T("bogo"))) {
start = 0x00C00000; start = 0x00C00000;
got = true; got = true;
if (currprefs.bogomem_size <= 0x100000) if (currprefs.bogomem_size <= 0x100000)
barrier = true; barrier = true;
} } else if (!_tcscmp(ab->label, _T("custmem1"))) {
else if (!_tcscmp(ab->label, _T("custmem1"))) {
start = currprefs.custom_memory_addrs[0]; start = currprefs.custom_memory_addrs[0];
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("custmem2"))) {
else if (!_tcscmp(ab->label, _T("custmem2"))) {
start = currprefs.custom_memory_addrs[1]; start = currprefs.custom_memory_addrs[1];
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("hrtmem"))) {
else if (!_tcscmp(ab->label, _T("hrtmem"))) {
start = 0x00a10000; start = 0x00a10000;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("arhrtmon"))) {
else if (!_tcscmp(ab->label, _T("arhrtmon"))) {
start = 0x00800000; start = 0x00800000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("xpower_e2"))) {
else if (!_tcscmp(ab->label, _T("xpower_e2"))) {
start = 0x00e20000; start = 0x00e20000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("xpower_f2"))) {
else if (!_tcscmp(ab->label, _T("xpower_f2"))) {
start = 0x00f20000; start = 0x00f20000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("nordic_f0"))) {
else if (!_tcscmp(ab->label, _T("nordic_f0"))) {
start = 0x00f00000; start = 0x00f00000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("nordic_f4"))) {
else if (!_tcscmp(ab->label, _T("nordic_f4"))) {
start = 0x00f40000; start = 0x00f40000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("nordic_f6"))) {
else if (!_tcscmp(ab->label, _T("nordic_f6"))) {
start = 0x00f60000; start = 0x00f60000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("superiv_b0"))) {
else if (!_tcscmp(ab->label, _T("superiv_b0"))) {
start = 0x00b00000; start = 0x00b00000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("superiv_d0"))) {
else if (!_tcscmp(ab->label, _T("superiv_d0"))) {
start = 0x00d00000; start = 0x00d00000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("superiv_e0"))) {
else if (!_tcscmp(ab->label, _T("superiv_e0"))) {
start = 0x00e00000; start = 0x00e00000;
barrier = true; barrier = true;
got = true; got = true;
} } else if (!_tcscmp(ab->label, _T("ram_a8"))) {
else if (!_tcscmp(ab->label, _T("ram_a8"))) {
start = 0x00a80000; start = 0x00a80000;
barrier = true; barrier = true;
got = true; got = true;
@ -396,8 +358,8 @@ bool uae_mman_info(addrbank *ab, struct uae_mman_data *md)
return got; return got;
} }
ATTRIBUTE_NO_SANITIZE_ADDRESS
bool mapped_malloc(addrbank *ab) bool mapped_malloc (addrbank *ab)
{ {
if (ab->allocated_size) { if (ab->allocated_size) {
write_log(_T("mapped_malloc with memory bank '%s' already allocated!?\n"), ab->name); write_log(_T("mapped_malloc with memory bank '%s' already allocated!?\n"), ab->name);
@ -415,7 +377,7 @@ bool mapped_malloc(addrbank *ab)
uaecptr start = ab->start; uaecptr start = ab->start;
if (uae_mman_info(ab, &md)) { if (uae_mman_info(ab, &md)) {
start = md.start; start = md.start;
ab->baseaddr = natmem_offset + start; ab->baseaddr = regs.natmem_offset + start;
} }
if (ab->baseaddr) { if (ab->baseaddr) {
@ -425,30 +387,31 @@ bool mapped_malloc(addrbank *ab)
} }
ab->allocated_size = ab->reserved_size; ab->allocated_size = ab->reserved_size;
write_log("mapped_malloc(): 0x%08x - 0x%08x (0x%08x - 0x%08x) -> %s (%s)\n", write_log("mapped_malloc(): 0x%08x - 0x%08x (0x%08x - 0x%08x) -> %s (%s)\n",
ab->baseaddr - natmem_offset, ab->baseaddr - natmem_offset + ab->allocated_size, ab->baseaddr - regs.natmem_offset, ab->baseaddr - regs.natmem_offset + ab->allocated_size,
ab->baseaddr, ab->baseaddr + ab->allocated_size, ab->name, ab->label); ab->baseaddr, ab->baseaddr + ab->allocated_size, ab->name, ab->label);
} }
ab->flags |= ABFLAG_DIRECTMAP; ab->flags |= ABFLAG_DIRECTMAP;
return (ab->baseaddr != nullptr); return (ab->baseaddr != NULL);
} }
ATTRIBUTE_NO_SANITIZE_ADDRESS
void mapped_free(addrbank *ab) void mapped_free (addrbank *ab)
{ {
if (ab->label != nullptr && !strcmp(ab->label, "filesys") && ab->baseaddr != nullptr) { if(ab->label != NULL && !strcmp(ab->label, "filesys") && ab->baseaddr != NULL) {
free(ab->baseaddr); free(ab->baseaddr);
write_log("mapped_free(): 0x%08x - 0x%08x (0x%08x - 0x%08x) -> %s (%s)\n", write_log("mapped_free(): 0x%08x - 0x%08x (0x%08x - 0x%08x) -> %s (%s)\n",
ab->baseaddr - natmem_offset, ab->baseaddr - natmem_offset + ab->allocated_size, ab->baseaddr - regs.natmem_offset, ab->baseaddr - regs.natmem_offset + ab->allocated_size,
ab->baseaddr, ab->baseaddr + ab->allocated_size, ab->name, ab->label); ab->baseaddr, ab->baseaddr + ab->allocated_size, ab->name, ab->label);
} }
ab->baseaddr = nullptr; ab->baseaddr = NULL;
ab->allocated_size = 0; ab->allocated_size = 0;
} }
void protect_roms(bool protect)
void protect_roms (bool protect)
{ {
/* /*
If this code is enabled, we can't switch back from JIT to nonJIT emulation... If this code is enabled, we can't switch back from JIT to nonJIT emulation...
if (protect) { if (protect) {
@ -468,10 +431,11 @@ void protect_roms(bool protect)
mprotect(rtarea, RTAREA_SIZE, protect ? PROT_READ : PROT_READ | PROT_WRITE); mprotect(rtarea, RTAREA_SIZE, protect ? PROT_READ : PROT_READ | PROT_WRITE);
if(filesysory != NULL) if(filesysory != NULL)
mprotect(filesysory, 0x10000, protect ? PROT_READ : PROT_READ | PROT_WRITE); mprotect(filesysory, 0x10000, protect ? PROT_READ : PROT_READ | PROT_WRITE);
*/ */
} }
static int doinit_shm()
static int doinit_shm (void)
{ {
expansion_scan_autoconfig(&currprefs, true); expansion_scan_autoconfig(&currprefs, true);
@ -484,17 +448,17 @@ static uae_u32 ofastmem_size[MAX_RAM_BOARDS];
static uae_u32 ortgmem_size[MAX_RTG_BOARDS]; static uae_u32 ortgmem_size[MAX_RTG_BOARDS];
static int ortgmem_type[MAX_RTG_BOARDS]; static int ortgmem_type[MAX_RTG_BOARDS];
bool init_shm() bool init_shm (void)
{ {
auto changed = false; bool changed = false;
for (auto i = 0; i < MAX_RAM_BOARDS; i++) { for (int i = 0; i < MAX_RAM_BOARDS; i++) {
if (oz3fastmem_size[i] != changed_prefs.z3fastmem[i].size) if (oz3fastmem_size[i] != changed_prefs.z3fastmem[i].size)
changed = true; changed = true;
if (ofastmem_size[i] != changed_prefs.fastmem[i].size) if (ofastmem_size[i] != changed_prefs.fastmem[i].size)
changed = true; changed = true;
} }
for (auto i = 0; i < MAX_RTG_BOARDS; i++) { for (int i = 0; i < MAX_RTG_BOARDS; i++) {
if (ortgmem_size[i] != changed_prefs.rtgboards[i].rtgmem_size) if (ortgmem_size[i] != changed_prefs.rtgboards[i].rtgmem_size)
changed = true; changed = true;
if (ortgmem_type[i] != changed_prefs.rtgboards[i].rtgmem_type) if (ortgmem_type[i] != changed_prefs.rtgboards[i].rtgmem_type)
@ -503,18 +467,18 @@ bool init_shm()
if (!changed) if (!changed)
return true; return true;
for (auto i = 0; i < MAX_RAM_BOARDS; i++) { for (int i = 0; i < MAX_RAM_BOARDS;i++) {
oz3fastmem_size[i] = changed_prefs.z3fastmem[i].size; oz3fastmem_size[i] = changed_prefs.z3fastmem[i].size;
ofastmem_size[i] = changed_prefs.fastmem[i].size; ofastmem_size[i] = changed_prefs.fastmem[i].size;
} }
for (auto i = 0; i < MAX_RTG_BOARDS; i++) { for (int i = 0; i < MAX_RTG_BOARDS; i++) {
ortgmem_size[i] = changed_prefs.rtgboards[i].rtgmem_size; ortgmem_size[i] = changed_prefs.rtgboards[i].rtgmem_size;
ortgmem_type[i] = changed_prefs.rtgboards[i].rtgmem_type; ortgmem_type[i] = changed_prefs.rtgboards[i].rtgmem_type;
} }
if (doinit_shm() < 0) if (doinit_shm () < 0)
return false; return false;
memory_hardreset(2); memory_hardreset (2);
return true; return true;
} }

View file

@ -418,8 +418,14 @@ void RefreshPanelCPU()
optFPUinternal->setEnabled(changed_prefs.cpu_model == 68040); optFPUinternal->setEnabled(changed_prefs.cpu_model == 68040);
chkFPUstrict->setSelected(changed_prefs.fpu_strict); chkFPUstrict->setSelected(changed_prefs.fpu_strict);
#ifdef USE_JIT_FPU
chkFPUJIT->setSelected(changed_prefs.compfpu); chkFPUJIT->setSelected(changed_prefs.compfpu);
chkFPUJIT->setEnabled(changed_prefs.cachesize > 0); chkFPUJIT->setEnabled(changed_prefs.cachesize > 0);
#else
chkFPUJIT->setSelected(false);
chkFPUJIT->setEnabled(false);
#endif
if (changed_prefs.m68k_speed == M68K_SPEED_7MHZ_CYCLES) if (changed_prefs.m68k_speed == M68K_SPEED_7MHZ_CYCLES)
opt7Mhz->setSelected(true); opt7Mhz->setSelected(true);

View file

@ -314,8 +314,6 @@ static void ShowSupportedResolutions (void)
#endif #endif
extern uae_u8 *natmem_offset;
static uae_u8 GetBytesPerPixel (uae_u32 RGBfmt) static uae_u8 GetBytesPerPixel (uae_u32 RGBfmt)
{ {
switch (RGBfmt) switch (RGBfmt)
@ -596,7 +594,7 @@ static bool rtg_render (void)
bool flushed = false; bool flushed = false;
if (!doskip ()) if (!doskip ())
flushed = picasso_flushpixels (gfxmem_banks[0]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[0]->start); flushed = picasso_flushpixels (gfxmem_banks[0]->start + regs.natmem_offset, picasso96_state.XYOffset - gfxmem_banks[0]->start);
return flushed; return flushed;
} }

View file

@ -1,28 +1,28 @@
/* /*
* sigsegv_linux_arm.cpp - x86_64 Linux SIGSEGV handler * sigsegv_linux_arm.cpp - x86_64 Linux SIGSEGV handler
* *
* Copyright (c) 2014 Jens Heitmann ARAnyM dev team (see AUTHORS) * Copyright (c) 2014 Jens Heitmann ARAnyM dev team (see AUTHORS)
* *
* Inspired by Bernie Meyer's UAE-JIT and Gwenole Beauchesne's Basilisk II-JIT * Inspired by Bernie Meyer's UAE-JIT and Gwenole Beauchesne's Basilisk II-JIT
* *
* This file is part of the ARAnyM project which builds a new and powerful * This file is part of the ARAnyM project which builds a new and powerful
* TOS/FreeMiNT compatible virtual machine running on almost any hardware. * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
* *
* ARAnyM is free software; you can redistribute it and/or modify * ARAnyM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* ARAnyM is distributed in the hope that it will be useful, * ARAnyM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with ARAnyM; if not, write to the Free Software * along with ARAnyM; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
#include "sysconfig.h" #include "sysconfig.h"
#include "sysdeps.h" #include "sysdeps.h"
@ -147,9 +147,9 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
} }
++in_handler; ++in_handler;
for (;;) { for(;;) {
// We analyse only exceptions from JIT // We analyse only exceptions from JIT
if (currprefs.cachesize == 0) { if(currprefs.cachesize == 0) {
output_log(_T("JIT not in use.\n")); output_log(_T("JIT not in use.\n"));
break; break;
} }
@ -157,7 +157,7 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
// Did the error happens in compiled code? // Did the error happens in compiled code?
if ((uae_u8*)fault_pc >= compiled_code && (uae_u8*)fault_pc < current_compile_p) if ((uae_u8*)fault_pc >= compiled_code && (uae_u8*)fault_pc < current_compile_p)
output_log(_T("Error in compiled code.\n")); output_log(_T("Error in compiled code.\n"));
else if ((uae_u8*)fault_pc >= popallspace && (uae_u8*)fault_pc < popallspace + POPALLSPACE_SIZE) else if((uae_u8*)fault_pc >= popallspace && (uae_u8*)fault_pc < popallspace + POPALLSPACE_SIZE)
output_log(_T("Error in popallspace code.\n")); output_log(_T("Error in popallspace code.\n"));
else { else {
output_log(_T("Error not in JIT code.\n")); output_log(_T("Error not in JIT code.\n"));
@ -165,10 +165,10 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
} }
// Get Amiga address of illegal memory address // Get Amiga address of illegal memory address
uintptr amiga_addr = (uae_u32)fault_addr - (uae_u32)natmem_offset; uintptr amiga_addr = (uae_u32) fault_addr - (uae_u32) regs.natmem_offset;
// Check for stupid RAM detection of kickstart // Check for stupid RAM detection of kickstart
if (a3000lmem_bank.allocated_size > 0 && amiga_addr >= a3000lmem_bank.start - 0x00100000 && amiga_addr < a3000lmem_bank.start - 0x00100000 + 8) { if(a3000lmem_bank.allocated_size > 0 && amiga_addr >= a3000lmem_bank.start - 0x00100000 && amiga_addr < a3000lmem_bank.start - 0x00100000 + 8) {
output_log(_T(" Stupid kickstart detection for size of ramsey_low at 0x%08x.\n"), amiga_addr); output_log(_T(" Stupid kickstart detection for size of ramsey_low at 0x%08x.\n"), amiga_addr);
pregs[ARM_REG_PC] += 4; pregs[ARM_REG_PC] += 4;
handled = HANDLE_EXCEPTION_A4000RAM; handled = HANDLE_EXCEPTION_A4000RAM;
@ -176,7 +176,7 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
} }
// Check for stupid RAM detection of kickstart // Check for stupid RAM detection of kickstart
if (a3000hmem_bank.allocated_size > 0 && amiga_addr >= a3000hmem_bank.start + a3000hmem_bank.allocated_size && amiga_addr < a3000hmem_bank.start + a3000hmem_bank.allocated_size + 8) { if(a3000hmem_bank.allocated_size > 0 && amiga_addr >= a3000hmem_bank.start + a3000hmem_bank.allocated_size && amiga_addr < a3000hmem_bank.start + a3000hmem_bank.allocated_size + 8) {
output_log(_T(" Stupid kickstart detection for size of ramsey_high at 0x%08x.\n"), amiga_addr); output_log(_T(" Stupid kickstart detection for size of ramsey_high at 0x%08x.\n"), amiga_addr);
pregs[ARM_REG_PC] += 4; pregs[ARM_REG_PC] += 4;
handled = HANDLE_EXCEPTION_A4000RAM; handled = HANDLE_EXCEPTION_A4000RAM;
@ -249,7 +249,7 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
if (transfer_type == TYPE_LOAD) { if (transfer_type == TYPE_LOAD) {
// Perform load via indirect memory call // Perform load via indirect memory call
uae_u32 oldval = pregs[rd]; uae_u32 oldval = pregs[rd];
switch (transfer_size) { switch(transfer_size) {
case SIZE_BYTE: case SIZE_BYTE:
pregs[rd] = style == STYLE_SIGNED ? (uae_s8)get_byte(amiga_addr) : (uae_u8)get_byte(amiga_addr); pregs[rd] = style == STYLE_SIGNED ? (uae_s8)get_byte(amiga_addr) : (uae_u8)get_byte(amiga_addr);
break; break;
@ -263,10 +263,9 @@ static int handle_exception(unsigned long *pregs, uintptr fault_addr)
break; break;
} }
output_log(_T("New value in %s: 0x%08x (old: 0x%08x)\n"), reg_names[rd], pregs[rd], oldval); output_log(_T("New value in %s: 0x%08x (old: 0x%08x)\n"), reg_names[rd], pregs[rd], oldval);
} } else {
else {
// Perform store via indirect memory call // Perform store via indirect memory call
switch (transfer_size) { switch(transfer_size) {
case SIZE_BYTE: { case SIZE_BYTE: {
put_byte(amiga_addr, pregs[rd]); put_byte(amiga_addr, pregs[rd]);
break; break;
@ -319,8 +318,8 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
int handled = handle_exception(regs, addr); int handled = handle_exception(regs, addr);
#if SHOW_DETAILS #if SHOW_DETAILS
if (handled != HANDLE_EXCEPTION_A4000RAM) { if(handled != HANDLE_EXCEPTION_A4000RAM) {
if (signum == 4) if(signum == 4)
output_log(_T("Illegal Instruction\n")); output_log(_T("Illegal Instruction\n"));
else else
output_log(_T("Segmentation Fault\n")); output_log(_T("Segmentation Fault\n"));
@ -329,7 +328,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
output_log(_T("info.si_errno = %d\n"), info->si_errno); output_log(_T("info.si_errno = %d\n"), info->si_errno);
output_log(_T("info.si_code = %d\n"), info->si_code); output_log(_T("info.si_code = %d\n"), info->si_code);
output_log(_T("info.si_addr = %08x\n"), info->si_addr); output_log(_T("info.si_addr = %08x\n"), info->si_addr);
if (signum == 4) if(signum == 4)
output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr))); output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr)));
output_log(_T("r0 = 0x%08x\n"), ucontext->uc_mcontext.arm_r0); output_log(_T("r0 = 0x%08x\n"), ucontext->uc_mcontext.arm_r0);
output_log(_T("r1 = 0x%08x\n"), ucontext->uc_mcontext.arm_r1); output_log(_T("r1 = 0x%08x\n"), ucontext->uc_mcontext.arm_r1);
@ -354,7 +353,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
output_log(_T("Old Mask = 0x%08x\n"), ucontext->uc_mcontext.oldmask); output_log(_T("Old Mask = 0x%08x\n"), ucontext->uc_mcontext.oldmask);
void *getaddr = (void *)ucontext->uc_mcontext.arm_lr; void *getaddr = (void *)ucontext->uc_mcontext.arm_lr;
if (dladdr(getaddr, &dlinfo)) if(dladdr(getaddr, &dlinfo))
output_log(_T("LR - 0x%08X: <%s> (%s)\n"), getaddr, dlinfo.dli_sname, dlinfo.dli_fname); output_log(_T("LR - 0x%08X: <%s> (%s)\n"), getaddr, dlinfo.dli_sname, dlinfo.dli_fname);
else else
output_log(_T("LR - 0x%08X: symbol not found\n"), getaddr); output_log(_T("LR - 0x%08X: symbol not found\n"), getaddr);
@ -362,14 +361,14 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
#endif #endif
#if SHOW_DETAILS > 1 #if SHOW_DETAILS > 1
if (handled != HANDLE_EXCEPTION_A4000RAM) { if(handled != HANDLE_EXCEPTION_A4000RAM) {
output_log(_T("Stack trace:\n")); output_log(_T("Stack trace:\n"));
#define MAX_BACKTRACE 20 #define MAX_BACKTRACE 20
void *array[MAX_BACKTRACE]; void *array[MAX_BACKTRACE];
int size = backtrace(array, MAX_BACKTRACE); int size = backtrace(array, MAX_BACKTRACE);
for (int i = 0; i<size; ++i) for(int i=0; i<size; ++i)
{ {
if (dladdr(array[i], &dlinfo)) { if (dladdr(array[i], &dlinfo)) {
const char *symname = dlinfo.dli_sname; const char *symname = dlinfo.dli_sname;
@ -381,7 +380,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
void *ip = (void*)ucontext->uc_mcontext.arm_r10; void *ip = (void*)ucontext->uc_mcontext.arm_r10;
void **bp = (void**)ucontext->uc_mcontext.arm_r10; void **bp = (void**)ucontext->uc_mcontext.arm_r10;
int f = 0; int f = 0;
while (bp && ip) { while(bp && ip) {
if (!dladdr(ip, &dlinfo)) { if (!dladdr(ip, &dlinfo)) {
output_log(_T("IP out of range\n")); output_log(_T("IP out of range\n"));
break; break;
@ -389,7 +388,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
const char *symname = dlinfo.dli_sname; const char *symname = dlinfo.dli_sname;
output_log(_T("%02d: 0x%08x <%s + 0x%08x> (%s)\n"), ++f, ip, symname, output_log(_T("%02d: 0x%08x <%s + 0x%08x> (%s)\n"), ++f, ip, symname,
(unsigned long)ip - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname); (unsigned long)ip - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname);
if (dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main")) if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
break; break;
ip = bp[1]; ip = bp[1];
bp = (void**)bp[0]; bp = (void**)bp[0];
@ -400,7 +399,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
void *bt[100]; void *bt[100];
int sz = backtrace(bt, 100); int sz = backtrace(bt, 100);
strings = backtrace_symbols(bt, sz); strings = backtrace_symbols(bt, sz);
for (int i = 0; i < sz; ++i) for(int i = 0; i < sz; ++i)
output_log(_T("%s\n"), strings[i]); output_log(_T("%s\n"), strings[i]);
output_log(_T("End of stack trace.\n")); output_log(_T("End of stack trace.\n"));
} }
@ -410,7 +409,7 @@ void signal_segv(int signum, siginfo_t* info, void*ptr)
if (handled != HANDLE_EXCEPTION_A4000RAM) { if (handled != HANDLE_EXCEPTION_A4000RAM) {
--max_signals; --max_signals;
if (max_signals <= 0) { if(max_signals <= 0) {
target_startup_msg(_T("Exception"), _T("Too many access violations. Please turn off JIT.")); target_startup_msg(_T("Exception"), _T("Too many access violations. Please turn off JIT."));
uae_restart(1, NULL); uae_restart(1, NULL);
return; return;
@ -444,7 +443,7 @@ void signal_buserror(int signum, siginfo_t* info, void*ptr)
output_log(_T("info.si_errno = %d\n"), info->si_errno); output_log(_T("info.si_errno = %d\n"), info->si_errno);
output_log(_T("info.si_code = %d\n"), info->si_code); output_log(_T("info.si_code = %d\n"), info->si_code);
output_log(_T("info.si_addr = %08x\n"), info->si_addr); output_log(_T("info.si_addr = %08x\n"), info->si_addr);
if (signum == 4) if(signum == 4)
output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr))); output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr)));
output_log(_T("r0 = 0x%08x\n"), ucontext->uc_mcontext.arm_r0); output_log(_T("r0 = 0x%08x\n"), ucontext->uc_mcontext.arm_r0);
output_log(_T("r1 = 0x%08x\n"), ucontext->uc_mcontext.arm_r1); output_log(_T("r1 = 0x%08x\n"), ucontext->uc_mcontext.arm_r1);
@ -469,18 +468,18 @@ void signal_buserror(int signum, siginfo_t* info, void*ptr)
output_log(_T("Old Mask = 0x%08x\n"), ucontext->uc_mcontext.oldmask); output_log(_T("Old Mask = 0x%08x\n"), ucontext->uc_mcontext.oldmask);
void *getaddr = (void *)ucontext->uc_mcontext.arm_lr; void *getaddr = (void *)ucontext->uc_mcontext.arm_lr;
if (dladdr(getaddr, &dlinfo)) if(dladdr(getaddr, &dlinfo))
output_log(_T("LR - 0x%08X: <%s> (%s)\n"), getaddr, dlinfo.dli_sname, dlinfo.dli_fname); output_log(_T("LR - 0x%08X: <%s> (%s)\n"), getaddr, dlinfo.dli_sname, dlinfo.dli_fname);
else else
output_log(_T("LR - 0x%08X: symbol not found\n"), getaddr); output_log(_T("LR - 0x%08X: symbol not found\n"), getaddr);
output_log(_T("Stack trace:\n")); output_log(_T("Stack trace:\n"));
#define MAX_BACKTRACE 20 #define MAX_BACKTRACE 20
void *array[MAX_BACKTRACE]; void *array[MAX_BACKTRACE];
int size = backtrace(array, MAX_BACKTRACE); int size = backtrace(array, MAX_BACKTRACE);
for (int i = 0; i<size; ++i) for(int i=0; i<size; ++i)
{ {
if (dladdr(array[i], &dlinfo)) { if (dladdr(array[i], &dlinfo)) {
const char *symname = dlinfo.dli_sname; const char *symname = dlinfo.dli_sname;
@ -492,7 +491,7 @@ void signal_buserror(int signum, siginfo_t* info, void*ptr)
void *ip = (void*)ucontext->uc_mcontext.arm_r10; void *ip = (void*)ucontext->uc_mcontext.arm_r10;
void **bp = (void**)ucontext->uc_mcontext.arm_r10; void **bp = (void**)ucontext->uc_mcontext.arm_r10;
int f = 0; int f = 0;
while (bp && ip) { while(bp && ip) {
if (!dladdr(ip, &dlinfo)) { if (!dladdr(ip, &dlinfo)) {
output_log(_T("IP out of range\n")); output_log(_T("IP out of range\n"));
break; break;
@ -500,7 +499,7 @@ void signal_buserror(int signum, siginfo_t* info, void*ptr)
const char *symname = dlinfo.dli_sname; const char *symname = dlinfo.dli_sname;
output_log(_T("%02d: 0x%08x <%s + 0x%08x> (%s)\n"), ++f, ip, symname, output_log(_T("%02d: 0x%08x <%s + 0x%08x> (%s)\n"), ++f, ip, symname,
(unsigned long)ip - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname); (unsigned long)ip - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname);
if (dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main")) if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
break; break;
ip = bp[1]; ip = bp[1];
bp = (void**)bp[0]; bp = (void**)bp[0];
@ -511,7 +510,7 @@ void signal_buserror(int signum, siginfo_t* info, void*ptr)
void *bt[100]; void *bt[100];
int sz = backtrace(bt, 100); int sz = backtrace(bt, 100);
strings = backtrace_symbols(bt, sz); strings = backtrace_symbols(bt, sz);
for (int i = 0; i < sz; ++i) for(int i = 0; i < sz; ++i)
output_log(_T("%s\n"), strings[i]); output_log(_T("%s\n"), strings[i]);
output_log(_T("End of stack trace.\n")); output_log(_T("End of stack trace.\n"));

View file

@ -16,7 +16,7 @@
#define AUTOCONFIG /* autoconfig support, fast ram, harddrives etc.. */ #define AUTOCONFIG /* autoconfig support, fast ram, harddrives etc.. */
#define JIT /* JIT compiler support */ #define JIT /* JIT compiler support */
#define USE_JIT_FPU #define USE_JIT_FPU
/* #define NATMEM_OFFSET natmem_offset */ /* #define NATMEM_OFFSET regs.natmem_offset */
/* #define CATWEASEL */ /* Catweasel MK2/3 support */ /* #define CATWEASEL */ /* Catweasel MK2/3 support */
/* #define AHI */ /* AHI sound emulation */ /* #define AHI */ /* AHI sound emulation */
/* #define ENFORCER */ /* UAE Enforcer */ /* #define ENFORCER */ /* UAE Enforcer */

View file

@ -13,7 +13,12 @@
#define OPTIONSFILENAME "uaeconfig" #define OPTIONSFILENAME "uaeconfig"
STATIC_INLINE FILE *uae_tfopen(const char *path, const char *mode) #ifndef ARMV6T2
#undef USE_JIT_FPU
#endif
STATIC_INLINE FILE *uae_tfopen(const TCHAR *path, const TCHAR *mode)
{ {
return fopen(path, mode); return fopen(path, mode);
} }
@ -27,7 +32,6 @@ extern int generic_main (int argc, char *argv[]);
extern int emulating; extern int emulating;
extern uae_u8* natmem_offset;
extern int z3base_adr; extern int z3base_adr;
extern unsigned long time_per_frame; extern unsigned long time_per_frame;