diff --git a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/arm64/assem_arm64.c b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/arm64/assem_arm64.c index d56b9ed5..84097657 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/arm64/assem_arm64.c +++ b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/arm64/assem_arm64.c @@ -848,6 +848,7 @@ static void alloc_cc(struct regstat *cur,int i) /* Assembler */ +#if ASSEM_DEBUG static char regname[32][4] = { "w0", "w1", @@ -915,11 +916,14 @@ static char regname64[32][4] = { "fp", "lr", "sp"}; +#endif +#if 0 static void output_byte(u_char byte) { *(out++)=byte; } +#endif static void output_w32(u_int word) { @@ -1170,11 +1174,13 @@ static void emit_zeroreg(int rt) output_w32(0x52800000|rt); } +#if 0 static void emit_zeroreg64(int rt) { assem_debug("movz %s,#0",regname64[rt]); output_w32(0xd2800000|rt); } +#endif static void emit_movz(u_int imm,u_int rt) { @@ -1211,6 +1217,7 @@ static void emit_movk(u_int imm,u_int rt) output_w32(0x72800000|imm<<5|rt); } +#if 0 static void emit_movk_lsl16(u_int imm,u_int rt) { assert(imm<65536); @@ -1301,6 +1308,7 @@ static void emit_movk64_lsl48(u_int imm,u_int rt) assem_debug("movk %s, #%d, lsl #%d",regname64[rt],imm,48); output_w32(0xf2e00000|imm<<5|rt); } +#endif static void emit_movimm(u_int imm,u_int rt) { @@ -1384,7 +1392,11 @@ static void emit_testimm(int rs,int imm) u_int armval, ret; assem_debug("tst %s,#%d",regname[rs],imm); ret=genimm(imm,32,&armval); +#ifdef NDEBUG + (void)ret; +#else assert(ret); +#endif output_w32(0x72000000|armval<<10|rs<<5|WZR); } @@ -1393,7 +1405,11 @@ static void emit_testimm64(int rs,int64_t imm) u_int armval, ret; assem_debug("tst %s,#%d",regname64[rs],imm); ret=genimm(imm,64,&armval); +#ifdef NDEBUG + (void)ret; +#else assert(ret); +#endif output_w32(0xf2000000|armval<<10|rs<<5|WZR); } @@ -1415,11 +1431,13 @@ static void emit_or(u_int rs1,u_int rs2,u_int rt) output_w32(0x2a000000|rs2<<16|rs1<<5|rt); } +#if 0 static void emit_orr64(u_int rs1,u_int rs2,u_int rt) { assem_debug("orr %s,%s,%s",regname64[rt],regname64[rs1],regname64[rs2]); output_w32(0xaa000000|rs2<<16|rs1<<5|rt); } +#endif static void emit_xor(u_int rs1,u_int rs2,u_int rt) { @@ -1504,6 +1522,7 @@ static void emit_addimm_no_flags(u_int imm,u_int rt) } #endif +#if 0 static void emit_addnop(u_int r) { assem_debug("nop"); @@ -1511,6 +1530,7 @@ static void emit_addnop(u_int r) /*assem_debug("add %s,%s,#0 (nop)",regname[r],regname[r]); output_w32(0x11000000|r<<5|r);*/ } +#endif static void emit_addimm64_32(int rsh,int rsl,int imm,int rth,int rtl) { @@ -1575,7 +1595,11 @@ static void emit_andimm64(int rs,int64_t imm,int rt) { u_int armval; uint32_t ret=genimm((uint64_t)imm,64,&armval); +#ifdef NDEBUG + (void)ret; +#else assert(ret); +#endif assem_debug("and %s,%s,#%d",regname64[rt],regname64[rs],imm); output_w32(0x92000000|armval<<10|rs<<5|rt); } @@ -1823,11 +1847,13 @@ static void emit_cmovs_imm(int imm,int rt) } } +#if 0 static void emit_cmove_reg(int rs,int rt) { assem_debug("csel %s,%s,%s,eq",regname[rt],regname[rs],regname[rt]); output_w32(0x1a800000|rt<<16|COND_EQ<<12|rs<<5|rt); } +#endif static void emit_cmovne_reg(int rs,int rt) { @@ -2063,12 +2089,14 @@ static void emit_jno(intptr_t a) output_w32(0x54000000|offset<<5|COND_VC); } +#if 0 static void emit_jcc(intptr_t a) { assem_debug("bcc %x",a); u_int offset=gencondjmp(a); output_w32(0x54000000|offset<<5|COND_CC); } +#endif static void emit_jae(intptr_t a) { @@ -2084,6 +2112,7 @@ static void emit_jb(intptr_t a) output_w32(0x54000000|offset<<5|COND_CC); } +#if 0 static void emit_pushreg(u_int r) { assert(0); @@ -2093,6 +2122,7 @@ static void emit_popreg(u_int r) { assert(0); } +#endif static void emit_jmpreg(u_int r) { @@ -2410,6 +2440,7 @@ static void emit_writedword(int rt, intptr_t addr) output_w32(0xf9000000|((offset>>3)<<10)|(FP<<5)|rt); } +#if 0 static void emit_writehword(int rt, int addr) { intptr_t offset = addr-(intptr_t)&g_dev.r4300.new_dynarec_hot_state; @@ -2426,6 +2457,7 @@ static void emit_writebyte(int rt, intptr_t addr) assem_debug("strb %s,fp+%d",regname[rt],offset); output_w32(0x39000000|offset<<10|(FP<<5)|rt); } +#endif static void emit_msub(u_int rs1,u_int rs2,u_int rs3,u_int rt) { @@ -2499,11 +2531,13 @@ static void emit_bic(u_int rs1,u_int rs2,u_int rt) output_w32(0x0a200000|rs2<<16|rs1<<5|rt); } +#if 0 static void emit_bic64(u_int rs1,u_int rs2,u_int rt) { assem_debug("bic %s,%s,%s",regname64[rt],regname64[rs1],regname64[rs2]); output_w32(0x8a200000|rs2<<16|rs1<<5|rt); } +#endif // Load 2 immediates optimizing for small code size static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2) @@ -2939,6 +2973,7 @@ static void emit_fcmpd(int x,int y) output_w32(0x1e602000|y<<16|x<<5); } +#if 0 static void emit_jno_unlikely(intptr_t a) { emit_jno(a); @@ -2949,6 +2984,7 @@ static void emit_breakpoint(u_int imm) assem_debug("brk #%d",imm); output_w32(0xd4200000|imm<<5); } +#endif static void emit_adr(intptr_t addr, int rt) { @@ -2974,6 +3010,7 @@ static void emit_adrp(intptr_t addr, int rt) assem_debug("adrp %d,#%d",regname64[rt],offset); output_w32(0x90000000|(offset&0x3)<<29|((offset>>2)&0x7ffff)<<5|rt); } +#if 0 static void emit_pc_relative_addr(intptr_t addr, int rt) { intptr_t out_rx=(intptr_t)out; @@ -2991,6 +3028,7 @@ static void emit_pc_relative_addr(intptr_t addr, int rt) } } } +#endif // Save registers before function call static void save_regs(u_int reglist) @@ -3085,7 +3123,9 @@ static void literal_pool_jumpover(int n) static void emit_extjump2(intptr_t addr, int target, intptr_t linker) { +#ifndef NDEBUG u_char *ptr=(u_char *)addr; +#endif assert(((ptr[3]&0xfc)==0x14)||((ptr[3]&0xff)==0x54)); //b or b.cond emit_movz_lsl16(((u_int)target>>16)&0xffff,1); @@ -3739,7 +3779,6 @@ static void fconv_assemble_arm64(int i,struct regstat *i_regs) if(i_regs->regmap[hr]>=0) reglist|=1<regmap,FSREG); save_regs(reglist); if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { @@ -4170,7 +4209,6 @@ static void float_assemble(int i,struct regstat *i_regs) if(i_regs->regmap[hr]>=0) reglist|=1<regmap,FSREG); if(opcode2[i]==0x10) { // Single precision save_regs(reglist); switch(source[i]&0x3f) diff --git a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c index df855289..ad6020f5 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c +++ b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c @@ -242,7 +242,9 @@ unsigned int stop_after_jal; static u_int start; static u_int *source; static u_int pagelimit; +#ifndef NDEBUG static char insn[MAXBLOCK][10]; +#endif static u_char itype[MAXBLOCK]; static u_char opcode[MAXBLOCK]; static u_char opcode2[MAXBLOCK]; @@ -2337,7 +2339,7 @@ static void tlb_speed_hacks() /**** Linker ****/ u_int verify_dirty(struct ll_entry * head) { - void *source; + void *source = NULL; if((int)head->start>=0xa0000000&&(int)head->start<0xa07fffff) { source=(void *)((uintptr_t)g_dev.rdram.dram+head->start-0xa0000000); }else if((int)head->start>=0xa4000000&&(int)head->start<0xa4001000) { @@ -2970,7 +2972,9 @@ void clean_blocks(u_int page) } } else if((signed int)head->vaddr>=(signed int)0xC0000000) { +#ifndef NDEBUG uintptr_t map_value=g_dev.r4300.new_dynarec_hot_state.memory_map[head->vaddr>>12]; +#endif start=head->start>>12; end=(head->start+head->length-1)>>12; for(i=start;i<=end;i++) { @@ -4568,7 +4572,7 @@ static void do_ccstub(int n) emit_loadreg(rs2[i],s2l); #endif int hr=0; - int addr,alt,ntaddr; + int addr=0,alt=0,ntaddr=0; while(hr= NEW_DYNAREC_ARM assert(map>=0); @@ -6934,7 +6938,9 @@ static void float_assemble(int i,struct regstat *i_regs) static void syscall_assemble(int i,struct regstat *i_regs) { +#ifndef NDEBUG signed char ccreg=get_reg(i_regs->regmap,CCREG); +#endif assert(ccreg==HOST_CCREG); assert(!is_delayslot); emit_movimm(start+i*4,0); // Get PC @@ -7158,7 +7164,7 @@ static void rjump_assemble(int i,struct regstat *i_regs) signed char *i_regmap=i_regs->regmap; #endif int temp; - int rs,cc; + int rs; rs=get_reg(branch_regs[i].regmap,rs1[i]); assert(rs>=0); if((rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1])&&(rs1[i]!=0)) { @@ -7212,7 +7218,9 @@ static void rjump_assemble(int i,struct regstat *i_regs) emit_prefetch(hash_table[((return_address>>16)^return_address)&0xFFFF]); #endif } - cc=get_reg(branch_regs[i].regmap,CCREG); +#ifndef NDEBUG + int cc=get_reg(branch_regs[i].regmap,CCREG); +#endif assert(cc==HOST_CCREG); #ifdef USE_MINI_HT int rh=get_reg(branch_regs[i].regmap,RHASH); @@ -8204,7 +8212,7 @@ static void pagespan_assemble(int i,struct regstat *i_regs) s1h=s2h=-1; } int hr=0; - int addr,alt,ntaddr; + int addr,alt=0,ntaddr=0; if(i_regs->regmap[HOST_BTREG]<0) {addr=HOST_BTREG;} else { while(hr= NEW_DYNAREC_ARM uintptr_t beginning=(uintptr_t)out; +#endif if((u_int)addr&1) { ds=1; pagespan_ds(); diff --git a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/x64/assem_x64.c b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/x64/assem_x64.c index 34116520..0b906b7f 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/x64/assem_x64.c +++ b/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/x64/assem_x64.c @@ -94,8 +94,7 @@ static void *add_pointer(void *src, void* addr) { int *ptr=(int*)src; int *ptr2=(int*)((uintptr_t)ptr+(uintptr_t)*ptr+4); - u_char *ptr3=(u_char*)ptr2; - assert((*(ptr3+1)&0xFF)==0x8d); //lea + assert((*(((u_char*)ptr2)+1)&0xFF)==0x8d); //lea u_int offset=(uintptr_t)addr-(uintptr_t)ptr-4; *ptr=offset; return (void*)ptr2; @@ -822,6 +821,7 @@ static void emit_lea8(int rs1,int rt) output_sib(3,rs1,5); output_w32(0); } +#if 0 static void emit_leairrx1(int imm,int rs1,int rs2,int rt) { assem_debug("lea %x(%%%s,%%%s,1),%%%s",imm,regname[rs1],regname[rs2],regname[rt]); @@ -850,6 +850,7 @@ static void emit_leairrx4(int imm,int rs1,int rs2,int rt) output_sib(2,rs2&7,rs1&7); } } +#endif static void emit_lea_rip(intptr_t addr, int hr) { @@ -1171,6 +1172,7 @@ static void emit_addimm_and_set_flags(int imm,int rt) output_w32(imm); } } +#if 0 static void emit_addimm_no_flags(int imm,int rt) { if(imm!=0) { @@ -1185,6 +1187,7 @@ static void emit_addimm_no_flags(int imm,int rt) } } } +#endif static void emit_adcimm(int imm,u_int rt) { @@ -1406,6 +1409,7 @@ static void emit_shrimm(int rs,u_int imm,int rt) } } +#if 0 static void emit_shrimm64(int rs,u_int imm,int rt) { assert(rs==rt); @@ -1423,6 +1427,7 @@ static void emit_shrimm64(int rs,u_int imm,int rt) emit_shrimm64(rt,imm,rt); } } +#endif static void emit_sarimm(int rs,u_int imm,int rt) { @@ -1862,6 +1867,7 @@ static void emit_jb(intptr_t a) output_w32(a-(intptr_t)out-4); } +#if 0 static void emit_pushimm(int imm) { assert(0); @@ -1869,6 +1875,7 @@ static void emit_pushimm(int imm) output_byte(0x68); output_w32(imm); } +#endif static void emit_pushreg(u_int r) { assem_debug("push %%%s",regname[r]); @@ -1883,6 +1890,7 @@ static void emit_popreg(u_int r) output_rex(0,0,0,r>>3); output_byte(0x58+(r&7)); } +#if 0 static void emit_callreg(u_int r) { assem_debug("call *%%%s",regname[r]); @@ -1890,6 +1898,7 @@ static void emit_callreg(u_int r) output_byte(0xFF); output_modrm(3,r,2); } +#endif static void emit_jmpreg(u_int r) { assem_debug("jmp *%%%s",regname[r]); @@ -1897,6 +1906,7 @@ static void emit_jmpreg(u_int r) output_byte(0xFF); output_modrm(3,r,4); } +#if 0 static void emit_jmpmem_indexed(u_int addr,u_int r) { assem_debug("jmp *%x(%%%s)",addr,regname[r]); @@ -1905,7 +1915,9 @@ static void emit_jmpmem_indexed(u_int addr,u_int r) output_modrm(2,r,4); output_w32(addr); } +#endif +#if 0 static void emit_addmem64(intptr_t addr,int hr) { assert(0); @@ -1930,6 +1942,7 @@ static void emit_submem64(intptr_t addr,int hr) output_modrm(0,5,hr&7); output_w32((intptr_t)addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#endif static void emit_readword(intptr_t addr, int rt) { @@ -2003,6 +2016,7 @@ static void emit_readdword_dualindexedx8(int rs1, int rs2, int rt) output_byte(0); } } +#if 0 static void emit_movmem_indexedx4(int addr, int rs, int rt) { assert(0); @@ -2046,6 +2060,7 @@ static void emit_movmem64_irrx8(int offset, int rs1, int rs2, int rt) output_sib(3,rs2&7,rs1&7); } } +#endif static void emit_movmem64(intptr_t addr, int rt) { assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL); @@ -2055,6 +2070,7 @@ static void emit_movmem64(intptr_t addr, int rt) output_modrm(0,5,rt&7); output_w32(addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#if 0 static void emit_readdword_indexed(intptr_t addr, int rs, int rt) { assem_debug("mov %x+%%%s,%%%s",addr,regname[rs],regname[rt]); @@ -2073,6 +2089,7 @@ static void emit_readdword_indexed(intptr_t addr, int rs, int rt) output_w32(addr); } } +#endif static void emit_readdword_indexed_tlb(int addr, int rs, int map, int rh, int rl) { assert(map>=0); @@ -2089,6 +2106,7 @@ static void emit_movsbl(intptr_t addr, int rt) output_modrm(0,5,rt); output_w32(addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#if 0 static void emit_movsbl_indexed(uintptr_t addr, int rs, int rt) { assert(addr<4294967296LL); @@ -2098,6 +2116,7 @@ static void emit_movsbl_indexed(uintptr_t addr, int rs, int rt) output_modrm(2,rs,rt); output_w32(addr); } +#endif static void emit_movsbl_indexed_tlb(int addr, int rs, int map, int rt) { assert(map>=0); @@ -2139,6 +2158,7 @@ static void emit_movswl(intptr_t addr, int rt) output_modrm(0,5,rt); output_w32(addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#if 0 static void emit_movswl_indexed(uintptr_t addr, int rs, int rt) { assert(addr<4294967296LL); @@ -2148,6 +2168,7 @@ static void emit_movswl_indexed(uintptr_t addr, int rs, int rt) output_modrm(2,rs,rt); output_w32(addr); } +#endif static void emit_movswl_indexed_tlb(int addr, int rs, int map, int rt) { assert(map>=0); @@ -2189,6 +2210,7 @@ static void emit_movzbl(intptr_t addr, int rt) output_modrm(0,5,rt); output_w32(addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#if 0 static void emit_movzbl_indexed(uintptr_t addr, int rs, int rt) { assert(addr<4294967296LL); @@ -2198,6 +2220,7 @@ static void emit_movzbl_indexed(uintptr_t addr, int rs, int rt) output_modrm(2,rs,rt); output_w32(addr); } +#endif static void emit_movzbl_indexed_tlb(int addr, int rs, int map, int rt) { assert(map>=0); @@ -2239,6 +2262,7 @@ static void emit_movzwl(intptr_t addr, int rt) output_modrm(0,5,rt); output_w32(addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#if 0 static void emit_movzwl_indexed(uintptr_t addr, int rs, int rt) { assert(addr<4294967296LL); @@ -2248,6 +2272,7 @@ static void emit_movzwl_indexed(uintptr_t addr, int rs, int rt) output_modrm(2,rs,rt); output_w32(addr); } +#endif static void emit_movzwl_indexed_tlb(int addr, int rs, int map, int rt) { assert(map>=0); @@ -2373,6 +2398,7 @@ static void emit_writedword_indexed_tlb(int rh, int rl, int addr, int rs, int ma emit_writeword_indexed_tlb(rh, addr, rs, map); emit_writeword_indexed_tlb(rl, addr+4, rs, map); } +#if 0 static void emit_writehword(int rt, int addr) { assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL); @@ -2398,6 +2424,7 @@ static void emit_writehword_indexed(int rt, intptr_t addr, int rs) output_w32(addr); } } +#endif static void emit_writehword_indexed_tlb(int rt, int addr, int rs, int map) { assert(map>=0); @@ -2431,6 +2458,7 @@ static void emit_writehword_indexed_tlb(int rt, int addr, int rs, int map) } } } +#if 0 static void emit_writebyte(int rt, int addr) { assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL); @@ -2456,6 +2484,7 @@ static void emit_writebyte_indexed(int rt, intptr_t addr, int rs) output_w32(addr); } } +#endif static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map) { assert(map>=0); @@ -2498,6 +2527,7 @@ static void emit_writeword_imm(int imm, intptr_t addr) output_w32(addr-(intptr_t)out-8); // Note: rip-relative in 64-bit mode output_w32(imm); } +#if 0 static void emit_writeword_imm_esp(int imm, intptr_t addr) { assert(0); @@ -2530,6 +2560,7 @@ static void emit_writebyte_imm(int imm, intptr_t addr) output_w32(addr-(intptr_t)out-5); // Note: rip-relative in 64-bit mode output_byte(imm); } +#endif static void emit_writedword(int rt, intptr_t addr) { assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL); @@ -2591,10 +2622,12 @@ static void emit_cmpmem_imm(intptr_t addr, int imm) } // special case for checking invalid_code +#if 0 static void emit_cmpmem_indexedsr12_imm(int addr,int r,int imm) { assert(0); } +#endif static void emit_cmpmem_indexedsr12_reg(int base,int r,int imm) { assert(imm<128&&imm>=-127); @@ -2645,6 +2678,7 @@ static void emit_readdword_dualindexed(int offset, int base,int rs,int rt) } // special case for checking memory_map in verify_mapping +#if 0 static void emit_cmpmem(intptr_t addr,int rt) { assert(0); @@ -2655,6 +2689,7 @@ static void emit_cmpmem(intptr_t addr,int rt) output_modrm(0,5,rt); output_w32((intptr_t)addr-(intptr_t)out-4); // Note: rip-relative in 64-bit mode } +#endif // Used to preload hash table entries #ifdef IMM_PREFETCH @@ -2866,6 +2901,7 @@ static void emit_fldcw_stack(void) output_modrm(0,4,5); output_sib(0,4,4); } +#if 0 static void emit_fldcw_indexed(intptr_t addr,int r) { assert(0); @@ -2875,6 +2911,7 @@ static void emit_fldcw_indexed(intptr_t addr,int r) output_sib(1,r,5); output_w32(addr); } +#endif static void emit_fldcw_indexedx4(int addr, int r) { assem_debug("fldcw (%%%s,%%%s,4)",regname[addr],regname[r]); @@ -3616,7 +3653,6 @@ static void fconv_assemble_x64(int i,struct regstat *i_regs) for(hr=0;hrregmap[hr]>=0) reglist|=1<regmap,FSREG); save_regs(reglist); if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { @@ -4021,7 +4057,6 @@ static void float_assemble(int i,struct regstat *i_regs) for(hr=0;hrregmap[hr]>=0) reglist|=1<regmap,FSREG); if(opcode2[i]==0x10) { // Single precision save_regs(reglist); switch(source[i]&0x3f) diff --git a/Source/3rdParty/mupen64plus-core/src/main/savestates.c b/Source/3rdParty/mupen64plus-core/src/main/savestates.c index 9a920d5c..dcbddded 100644 --- a/Source/3rdParty/mupen64plus-core/src/main/savestates.c +++ b/Source/3rdParty/mupen64plus-core/src/main/savestates.c @@ -1461,7 +1461,8 @@ int savestates_load(void) fPtr = osal_file_open(filepath, "rb"); // can I open this? if (fPtr == NULL) { - main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Failed to open savestate file %s", filepath); + if (filepath != NULL) + main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Failed to open savestate file %s", filepath); if (filepath != NULL) free(filepath); filepath = NULL;