{\r
int d_reg=0;\r
if (shift) {\r
- ot(" mov r%d,r%d,asl #%d\n",v,d_reg,shift);\r
- ot(" mov%s r%d,r%d,asr #%d\n",s,v,v,shift);\r
+ SignExtend(v, d_reg, size);\r
d_reg=v;\r
flags_set=1;\r
}\r
case 1:\r
if (type != earwt_zero_extend)\r
{\r
- ot(" mov r1,r%d,lsl #16\n",v);\r
- ot(" mov r1,r1,lsr #16\n");\r
+ ZeroExtend(1, v, size);\r
break;\r
}\r
// fallthrough\r
ifdef CONFIG_FILE
CFLAGS += -DCONFIG_FILE="\"$(CONFIG_FILE)\""
endif
+ifdef HAVE_ARMv6
+CFLAGS += -DHAVE_ARMv6=$(HAVE_ARMv6)
+endif
CXXFLAGS += $(CFLAGS)
OBJS = Main.o Ea.o OpAny.o OpArith.o OpBranch.o OpLogic.o OpMove.o Disa/Disa.o
ot(" orreq r10,r10,#0x40000000 ;@ get NZ, clear CV\n");\r
}\r
\r
+// size 0=8bit, 1=16bit\r
+void SignExtend(int rd, int rs, int size)\r
+{\r
+ if (size >= 2)\r
+ {\r
+ if (rd != rs)\r
+ ot(" mov r%d,r%d\n", rd, rs);\r
+ return;\r
+ }\r
+#if defined(HAVE_ARMv6) && (HAVE_ARMv6)\r
+ if (size == 1)\r
+ ot(" sxth r%d,r%d ;@ sign extend\n", rd, rs);\r
+ else\r
+ ot(" sxtb r%d,r%d ;@ sign extend\n", rd, rs);\r
+#else\r
+ int shift = size ? 16 : 24;\r
+ ot(" mov r%d,r%d,asl #%d\n", rd, rs, shift);\r
+ ot(" mov r%d,r%d,asr #%d ;@ sign extend\n", rd, rd, shift);\r
+#endif\r
+}\r
+\r
+void ZeroExtend(int rd, int rs, int size)\r
+{\r
+ if (size >= 2)\r
+ {\r
+ if (rd != rs)\r
+ ot(" mov r%d,r%d\n", rd, rs);\r
+ return;\r
+ }\r
+#if defined(HAVE_ARMv6) && (HAVE_ARMv6)\r
+ if (size == 1)\r
+ ot(" uxth r%d,r%d ;@ zero extend\n", rd, rs);\r
+ else\r
+#else\r
+ if (size == 1)\r
+ {\r
+ ot(" mov r%d,r%d,lsl #16\n", rd, rs);\r
+ ot(" mov r%d,r%d,lsr #16 ;@ zero extend\n", rd, rd);\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ ot(" and r%d,r%d,#0xff ;@ zero extend\n", rd, rs);\r
+ }\r
+}\r
+\r
// -----------------------------------------------------------------\r
\r
int g_op;\r
extern int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace;\r
int OpGetFlags(int subtract,int xbit,int sprecialz=0);\r
void OpGetFlagsNZ(int rd);\r
+void SignExtend(int rd, int rs, int size);\r
+void ZeroExtend(int rd, int rs, int size);\r
void OpUse(int op,int use);\r
void OpStart(int op,int sea=0,int tea=0,int op_changes_cycles=0,int supervisor_check=0);\r
void OpEnd(int sea=0,int tea=0);\r
**/\r
\r
\r
+/*\r
+ * By default, only ARMv4 instructions are used.\r
+ * If you want Cyclone to make use of newer ARM instructions, enable the\r
+ * options(s) below. You can also override this using make argument:\r
+ * make HAVE_ARMv6=1\r
+ */\r
+#ifndef HAVE_ARMv6\r
+#define HAVE_ARMv6 0\r
+#endif\r
+\r
/*\r
* If this option is enabled, Microsoft ARMASM compatible output is generated\r
* (output file - Cyclone.asm). Otherwise GNU as syntax is used (Cyclone.s).\r