* Some basic information about the the target CPU *
*************************************************************************/
-#define EAX 0
-#define ECX 1
-#define EDX 2
-#define EBX 3
+#define EAX_INDEX 0
+#define ECX_INDEX 1
+#define EDX_INDEX 2
+#define EBX_INDEX 3
+#define ESP_INDEX 4
+#define EBP_INDEX 5
+#define ESI_INDEX 6
+#define EDI_INDEX 7
+#if defined(__x86_64__)
+#define R8_INDEX 8
+#define R9_INDEX 9
+#define R10_INDEX 10
+#define R11_INDEX 11
+#define R12_INDEX 12
+#define R13_INDEX 13
+#define R14_INDEX 14
+#define R15_INDEX 15
+#endif
+/* XXX this has to match X86_Reg8H_Base + 4 */
+#define AH_INDEX (0x10+4+EAX_INDEX)
+#define CH_INDEX (0x10+4+ECX_INDEX)
+#define DH_INDEX (0x10+4+EDX_INDEX)
+#define BH_INDEX (0x10+4+EBX_INDEX)
/* The register in which subroutines return an integer return value */
-#define REG_RESULT EAX
+#define REG_RESULT EAX_INDEX
/* The registers subroutines take their first and second argument in */
-#ifdef _WIN32
-/* MSVC __fastcall registers are ECX and EDX */
-#define REG_PAR1 ECX
-#define REG_PAR2 EDX
+#if defined(_WIN32)
+/* Handle the _fastcall parameters of ECX and EDX */
+#define REG_PAR1 ECX_INDEX
+#define REG_PAR2 EDX_INDEX
+#elif defined(__x86_64__)
+#define REG_PAR1 EDI_INDEX
+#define REG_PAR2 ESI_INDEX
#else
-#define REG_PAR1 EAX
-#define REG_PAR2 EDX
+#define REG_PAR1 EAX_INDEX
+#define REG_PAR2 EDX_INDEX
#endif
-/* Three registers that are not used for any of the above */
-#define REG_NOPAR1 6
-#define REG_NOPAR2 5
-#define REG_NOPAR3 3
+#if defined(_WIN32)
+#define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */
+#define REG_PC_TMP ECX_INDEX
+#define SHIFTCOUNT_NREG ECX_INDEX /* Register that can be used for shiftcount. -1 if any reg will do */
+#else
+#define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */
+#define REG_PC_TMP ECX_INDEX /* Another register that is not the above */
+#define SHIFTCOUNT_NREG ECX_INDEX /* Register that can be used for shiftcount. -1 if any reg will do */
+#endif
-#define REG_PC_PRE 0 /* The register we use for preloading regs.pc_p */
-#define REG_PC_TMP 1 /* Another register that is not the above */
+#define MUL_NREG1 EAX_INDEX /* %eax will hold the low 32 bits after a 32x32 mul */
+#define MUL_NREG2 EDX_INDEX /* %edx will hold the high 32 bits */
-#define SHIFTCOUNT_NREG 1 /* Register that can be used for shiftcount.
- -1 if any reg will do */
-#define MUL_NREG1 0 /* %eax will hold the low 32 bits after a 32x32 mul */
-#define MUL_NREG2 2 /* %edx will hold the high 32 bits */
+#define STACK_ALIGN 16
+#define STACK_OFFSET sizeof(void *)
uae_s8 always_used[]={4,-1};
+#if defined(__x86_64__)
+uae_s8 can_byte[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
+uae_s8 can_word[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1};
+#else
uae_s8 can_byte[]={0,1,2,3,-1};
uae_s8 can_word[]={0,1,2,3,5,6,7,-1};
+#endif
uae_u8 call_saved[]={0,0,0,0,1,0,0,0};
addrbank *ab = &get_mem_bank (addr);
if (!ab)
return 0;
+ if (ab->flags & ABFLAG_SAFE)
+ return 1;
if (!ab->check (addr, size))
return 0;
- if (ab->flags == ABFLAG_RAM || ab->flags == ABFLAG_ROM || ab->flags == ABFLAG_ROMIN)
+ if (ab->flags & (ABFLAG_RAM | ABFLAG_ROM | ABFLAG_ROMIN | ABFLAG_SAFE))
return 1;
return 0;
}
static uae_u8 *illgdebug;
static int illgdebug_break;
+static void illg_free (void)
+{
+ free (illgdebug);
+ illgdebug = NULL;
+}
+
static void illg_init (void)
{
int i;
+ uae_u8 c = 3;
+ uaecptr addr, end;
- free (illgdebug);
- illgdebug = (uae_u8*)xmalloc (0x1000000);
+ illgdebug = (uae_u8*)xcalloc (0x01000000, 1);
if (!illgdebug)
return;
- memset (illgdebug, 3, 0x1000000);
- memset (illgdebug, 0, currprefs.chipmem_size);
- memset (illgdebug + 0xc00000, 0, currprefs.bogomem_size);
- memset (illgdebug + 0x200000, 0, currprefs.fastmem_size);
+ addr = 0xffffffff;
+ while ((addr = nextaddr(addr, &end)) != 0xffffffff) {
+ if (end < 0x01000000)
+ memset (illgdebug + addr, c, end - addr);
+ addr = end - 1;
+ }
i = 0;
while (custd[i].name) {
int rw = custd[i].rw;
for (i = 0; i < 16; i++) { /* CIAs */
if (i == 11)
continue;
- illgdebug[0xbfe001 + i * 0x100] = 0;
- illgdebug[0xbfd000 + i * 0x100] = 0;
+ illgdebug[0xbfe001 + i * 0x100] = c;
+ illgdebug[0xbfd000 + i * 0x100] = c;
}
memset (illgdebug + 0xf80000, 1, 512 * 1024); /* KS ROM */
- memset (illgdebug + 0xdc0000, 0, 0x3f); /* clock */
+ memset (illgdebug + 0xdc0000, c, 0x3f); /* clock */
#ifdef CDTV
if (currprefs.cs_cdtvram) {
- memset (illgdebug + 0xdc8000, 0, 4096); /* CDTV batt RAM */
+ memset (illgdebug + 0xdc8000, c, 4096); /* CDTV batt RAM */
memset (illgdebug + 0xf00000, 1, 256 * 1024); /* CDTV ext ROM */
}
#endif
#ifdef CD32
if (currprefs.cs_cd32cd) {
- memset (illgdebug + AKIKO_BASE, 0, AKIKO_BASE_END - AKIKO_BASE);
+ memset (illgdebug + AKIKO_BASE, c, AKIKO_BASE_END - AKIKO_BASE);
memset (illgdebug + 0xe00000, 1, 512 * 1024); /* CD32 ext ROM */
}
#endif
for (i = size - 1; i >= 0; i--) {
uae_u8 v = val >> (i * 8);
uae_u32 ad = addr + i;
- if (ad >= 0x1000000)
+ if (ad >= 0x01000000)
mask = 7;
else
mask = illgdebug[ad];
- if (!mask)
- continue;
+ if ((mask & 3) == 3)
+ return;
if (mask & 0x80) {
illg_debug_check (ad, rwi, size, val);
- } else if ((mask & 3) == 3) {
+ } else if ((mask & 3) == 0) {
if (rwi & 2)
console_out ("W: %08.8X=%02.2X PC=%08.8X\n", ad, v, pc);
else if (rwi & 1)
console_out ("R: %08.8X PC=%08.8X\n", ad, pc);
if (illgdebug_break)
activate_debugger ();
- } else if ((mask & 1) && (rwi & 1)) {
+ } else if (!(mask & 1) && (rwi & 1)) {
console_out ("RO: %08.8X=%02.2X PC=%08.8X\n", ad, v, pc);
if (illgdebug_break)
activate_debugger ();
- } else if ((mask & 2) && (rwi & 2)) {
+ } else if (!(mask & 2) && (rwi & 2)) {
console_out ("WO: %08.8X PC=%08.8X\n", ad, pc);
if (illgdebug_break)
activate_debugger ();
}
}
+static void initialize_memwatch (int mode);
static void smc_detect_init(void)
{
xfree(smc_table);
smc_size = currprefs.z3fastmem_start + currprefs.z3fastmem_size;
smc_size += 4;
smc_table = (struct smc_item*)xmalloc (smc_size * sizeof (struct smc_item));
+ if (!smc_table)
+ return;
smc_reset();
+ if (!memwatch_enabled)
+ initialize_memwatch (0);
console_out("SMCD enabled\n");
}
console_out ("cleared logging addresses %08.8X - %08.8X\n", addr, addr + len);
while (len > 0) {
addr &= 0xffffff;
- illgdebug[addr] = 0;
+ illgdebug[addr] = 7;
addr++;
len--;
}
+ } else {
+ illg_free();
+ console_out("Illegal memory access logging disabled\n");
}
} else {
illg_init ();
}
}
-
static void writeintomem (char **c)
{
uae_u32 addr = 0;
break;
case i_ASR:
- mayfail;
+ mayfail;
if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " return 0;\n"
- "} \n");
- start_brace();
+ comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " return 0;\n"
+ "} \n");
+ start_brace();
}
comprintf("\tdont_care_flags();\n");
comprintf("\tint highmask;\n"
"\tint width;\n"
"\tint cdata=scratchie++;\n"
- "\tint sdata=scratchie++;\n"
- "\tint tmpcnt=scratchie++;\n");
- comprintf("\tmov_l_rr(sdata,data);\n"
- "\tmov_l_rr(cdata,data);\n"
- "\tmov_l_rr(tmpcnt,cnt);\n");
- switch (curi->size) {
- case sz_byte: comprintf("\tshra_b_ri(sdata,7);\n"); break;
- case sz_word: comprintf("\tshra_w_ri(sdata,15);\n"); break;
- case sz_long: comprintf("\tshra_l_ri(sdata,31);\n"); break;
- default: abort();
+ "\tint tmpcnt=scratchie++;\n"
+ "\tint highshift=scratchie++;\n");
+ comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
+ "\tand_l_ri(tmpcnt,63);\n"
+ "\tmov_l_ri(cdata,0);\n"
+ "\tcmov_l_rr(cdata,data,5);\n");
+ /* cdata is now either data (for shift count!=0) or
+ 0 (for shift count==0) */
+ switch(curi->size) {
+ case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
+ "\thighmask=0x38;\n"
+ "\twidth=8;\n");
+ break;
+ case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
+ "\thighmask=0x30;\n"
+ "\twidth=16;\n");
+ break;
+ case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
+ "\thighmask=0x20;\n"
+ "\twidth=32;\n");
+ break;
+ default: abort();
}
- /* sdata is now the MSB propagated to all bits for the
- register of specified size */
- comprintf("\tand_l_ri(tmpcnt,63);\n");
+ comprintf("test_l_ri(cnt,highmask);\n"
+ "mov_l_ri(highshift,0);\n"
+ "mov_l_ri(scratchie,width/2);\n"
+ "cmov_l_rr(highshift,scratchie,5);\n");
+ /* The x86 masks out bits, so we now make sure that things
+ really get shifted as much as planned */
switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,tmpcnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshra_w_rr(data,tmpcnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshra_l_rr(data,tmpcnt);\n"
- "\thighmask=0x20;\n");
- break;
+ case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
+ case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
+ case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
+ default: abort();
}
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n");
- switch (curi->size) {
- case sz_byte: comprintf("\tcmov_b_rr(data,sdata,NATIVE_CC_NE);\n"); break;
- case sz_word: comprintf("\tcmov_w_rr(data,sdata,NATIVE_CC_NE);\n"); break;
- case sz_long: comprintf("\tcmov_l_rr(data,sdata,NATIVE_CC_NE);\n"); break;
+ /* And again */
+ switch(curi->size) {
+ case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
+ case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
+ case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
+ default: abort();
}
-
+
/* Result of shift is now in data. Now we need to determine
the carry by shifting cdata one less */
- /* NOTE: carry bit is cleared if shift count is zero */
- comprintf("\tmov_l_ri(scratchie,0);\n"
- "\ttest_l_rr(tmpcnt,tmpcnt);\n"
- "\tcmov_l_rr(sdata,scratchie,NATIVE_CC_EQ);\n"
- "\tforget_about(scratchie);\n");
comprintf("\tsub_l_ri(tmpcnt,1);\n");
switch(curi->size) {
case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break;
default: abort();
}
/* If the shift count was higher than the width, we need
- to pick up the sign from original data (sdata) */
- /* NOTE: for shift count of zero, the following holds
- true and cdata contains 0 so that carry bit is cleared */
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n"
- "\tforget_about(tmpcnt);\n"
- "\tcmov_l_rr(cdata,sdata,NATIVE_CC_NE);\n");
-
- /* And create the flags (preserve X flag if shift count is zero) */
- comprintf("\ttest_l_ri(cnt,63);\n"
- "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n");
+ to pick up the sign from data */
+ comprintf("test_l_ri(tmpcnt,highmask);\n"
+ "cmov_l_rr(cdata,data,5);\n");
+ /* And create the flags */
comprintf("\tstart_needflags();\n");
comprintf("\tif (needed_flags & FLAG_ZNV)\n");
switch(curi->size) {
comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
comprintf("\t live_flags();\n");
comprintf("\t end_needflags();\n");
+ comprintf("\t duplicate_carry();\n");
comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
genastore ("data", curi->dmode, "dstreg", curi->size, "data");
}
switch(curi->size) {
case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
"\thighmask=0x38;\n"
- "\twidth=8;\n");
+ "\twidth=8;\n");
break;
case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
"\thighmask=0x30;\n"
- "\twidth=16;\n");
+ "\twidth=16;\n");
break;
case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
"\thighmask=0x20;\n"
- "\twidth=32;\n");
+ "\twidth=32;\n");
break;
default: abort();
}
break;
case i_LSR:
- mayfail;
+ mayfail;
if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " return 0;\n"
- "} \n");
- start_brace();
+ comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " return 0;\n"
+ "} \n");
+ start_brace();
}
comprintf("\tdont_care_flags();\n");
comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
"\tand_l_ri(tmpcnt,63);\n"
"\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,NATIVE_CC_NE);\n");
+ "\tcmov_l_rr(cdata,data,5);\n");
/* cdata is now either data (for shift count!=0) or
0 (for shift count==0) */
switch(curi->size) {
- case sz_byte: comprintf("\tshrl_b_rr(data,tmpcnt);\n"
- "\thighmask=0x38;\n");
+ case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
+ "\thighmask=0x38;\n");
break;
- case sz_word: comprintf("\tshrl_w_rr(data,tmpcnt);\n"
- "\thighmask=0x30;\n");
+ case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
+ "\thighmask=0x30;\n");
break;
- case sz_long: comprintf("\tshrl_l_rr(data,tmpcnt);\n"
- "\thighmask=0x20;\n");
+ case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
+ "\thighmask=0x20;\n");
break;
default: abort();
}
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n"
- "\rmov_l_ri(scratchie,0);\n");
- if (curi->size == sz_long)
- comprintf("\tcmov_l_rr(data,scratchie,NATIVE_CC_NE);\n");
- else {
- comprintf("\tcmov_l_rr(scratchie,data,NATIVE_CC_EQ);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- default: abort();
- }
+ comprintf("test_l_ri(cnt,highmask);\n"
+ "mov_l_ri(scratchie,0);\n"
+ "cmov_l_rr(scratchie,data,4);\n");
+ switch(curi->size) {
+ case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
+ case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
+ case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
+ default: abort();
}
/* Result of shift is now in data. Now we need to determine
the carry by shifting cdata one less */
comprintf("\tsub_l_ri(tmpcnt,1);\n");
- comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n");
- comprintf("\tforget_about(tmpcnt);\n");
- if (curi->size != sz_long) /* scratchie is still live for LSR.L */
- comprintf("\tmov_l_ri(scratchie,0);\n");
- comprintf("\tcmov_l_rr(cdata,scratchie,NATIVE_CC_NE);\n");
- comprintf("\tforget_about(scratchie);\n");
- /* And create the flags (preserve X flag if shift count is zero) */
- comprintf("\ttest_l_ri(cnt,63);\n"
- "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n");
+ switch(curi->size) {
+ case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break;
+ case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break;
+ case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break;
+ default: abort();
+ }
+ comprintf("test_l_ri(tmpcnt,highmask);\n"
+ "mov_l_ri(scratchie,0);\n"
+ "cmov_l_rr(cdata,scratchie,5);\n");
+ /* And create the flags */
comprintf("\tstart_needflags();\n");
comprintf("\tif (needed_flags & FLAG_ZNV)\n");
switch(curi->size) {
comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
comprintf("\t live_flags();\n");
comprintf("\t end_needflags();\n");
+ comprintf("\t duplicate_carry();\n");
comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
genastore ("data", curi->dmode, "dstreg", curi->size, "data");
}
comprintf("\tint highmask;\n");
switch(curi->size) {
case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
+ "\thighmask=0x38;\n");
break;
case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
+ "\thighmask=0x30;\n");
break;
case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
+ "\thighmask=0x20;\n");
break;
default: abort();
}
break;
case i_LSL:
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " return 0;\n"
- "} \n");
- start_brace();
- }
comprintf("\tdont_care_flags();\n");
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
"\tand_l_ri(tmpcnt,63);\n"
"\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,NATIVE_CC_NE);\n");
+ "\tcmov_l_rr(cdata,data,5);\n");
/* cdata is now either data (for shift count!=0) or
0 (for shift count==0) */
switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(data,tmpcnt);\n"
- "\thighmask=0x38;\n");
+ case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
+ "\thighmask=0x38;\n");
break;
- case sz_word: comprintf("\tshll_w_rr(data,tmpcnt);\n"
- "\thighmask=0x30;\n");
+ case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
+ "\thighmask=0x30;\n");
break;
- case sz_long: comprintf("\tshll_l_rr(data,tmpcnt);\n"
- "\thighmask=0x20;\n");
+ case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
+ "\thighmask=0x20;\n");
break;
default: abort();
}
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n"
- "\tmov_l_ri(scratchie,0);\n");
- if (curi->size == sz_long)
- comprintf("\tcmov_l_rr(data,scratchie,NATIVE_CC_NE);\n");
- else {
- comprintf("\tcmov_l_rr(scratchie,data,NATIVE_CC_EQ);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- default: abort();
- }
+ comprintf("test_l_ri(cnt,highmask);\n"
+ "mov_l_ri(scratchie,0);\n"
+ "cmov_l_rr(scratchie,data,4);\n");
+ switch(curi->size) {
+ case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
+ case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
+ case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
+ default: abort();
}
/* Result of shift is now in data. Now we need to determine
the carry by shifting cdata one less */
comprintf("\tsub_l_ri(tmpcnt,1);\n");
- comprintf("\tshll_l_rr(cdata,tmpcnt);\n");
- comprintf("\ttest_l_ri(tmpcnt,highmask);\n");
- comprintf("\tforget_about(tmpcnt);\n");
- if (curi->size != sz_long) /* scratchie is still live for LSL.L */
- comprintf("\tmov_l_ri(scratchie,0);\n");
- comprintf("\tcmov_l_rr(cdata,scratchie,NATIVE_CC_NE);\n");
- comprintf("\tforget_about(scratchie);\n");
- /* And create the flags (preserve X flag if shift count is zero) */
- switch (curi->size) {
- case sz_byte: comprintf("\tshrl_l_ri(cdata,7);\n"); break;
- case sz_word: comprintf("\tshrl_l_ri(cdata,15);\n"); break;
- case sz_long: comprintf("\tshrl_l_ri(cdata,31);\n"); break;
+ switch(curi->size) {
+ case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
+ case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
+ case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
+ default: abort();
}
- comprintf("\ttest_l_ri(cnt,63);\n"
- "\tcmov_l_rr(FLAGX,cdata,NATIVE_CC_NE);\n");
+ comprintf("test_l_ri(tmpcnt,highmask);\n"
+ "mov_l_ri(scratchie,0);\n"
+ "cmov_l_rr(cdata,scratchie,5);\n");
+ /* And create the flags */
comprintf("\tstart_needflags();\n");
comprintf("\tif (needed_flags & FLAG_ZNV)\n");
switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
+ case sz_byte: comprintf("\t test_b_rr(data,data);\n");
+ comprintf("\t bt_l_ri(cdata,7);\n"); break;
+ case sz_word: comprintf("\t test_w_rr(data,data);\n");
+ comprintf("\t bt_l_ri(cdata,15);\n"); break;
+ case sz_long: comprintf("\t test_l_rr(data,data);\n");
+ comprintf("\t bt_l_ri(cdata,31);\n"); break;
}
- comprintf("\t bt_l_ri(cdata,0);\n");
comprintf("\t live_flags();\n");
comprintf("\t end_needflags();\n");
+ comprintf("\t duplicate_carry();\n");
comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
genastore ("data", curi->dmode, "dstreg", curi->size, "data");
}
comprintf("\tint highmask;\n");
switch(curi->size) {
case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
+ "\thighmask=0x38;\n");
break;
case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
+ "\thighmask=0x30;\n");
break;
case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
+ "\thighmask=0x20;\n");
break;
default: abort();
}
}
break;
-
case i_ROL:
mayfail;
if (curi->smode==Dreg) {