From 198817609e33a09e825e71e85118d1b07ecdf645 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 6 Oct 2014 02:49:56 +0300 Subject: [PATCH] support a few ARMv6 instructions --- Ea.cpp | 6 ++---- Makefile | 3 +++ OpAny.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ app.h | 2 ++ config.h | 10 ++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/Ea.cpp b/Ea.cpp index fc4dff9..5969529 100644 --- a/Ea.cpp +++ b/Ea.cpp @@ -372,8 +372,7 @@ int EaRead(int a,int v,int ea,int size,int mask,EaRWType type,int set_nz) { int d_reg=0; if (shift) { - ot(" mov r%d,r%d,asl #%d\n",v,d_reg,shift); - ot(" mov%s r%d,r%d,asr #%d\n",s,v,v,shift); + SignExtend(v, d_reg, size); d_reg=v; flags_set=1; } @@ -498,8 +497,7 @@ int EaWrite(int a,int v,int ea,int size,int mask,EaRWType type) case 1: if (type != earwt_zero_extend) { - ot(" mov r1,r%d,lsl #16\n",v); - ot(" mov r1,r1,lsr #16\n"); + ZeroExtend(1, v, size); break; } // fallthrough diff --git a/Makefile b/Makefile index 8b7a5fd..98a578a 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ CFLAGS += -Wall -ggdb 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 diff --git a/OpAny.cpp b/OpAny.cpp index 8cb8c09..64e2bfe 100644 --- a/OpAny.cpp +++ b/OpAny.cpp @@ -165,6 +165,52 @@ void OpGetFlagsNZ(int rd) ot(" orreq r10,r10,#0x40000000 ;@ get NZ, clear CV\n"); } +// size 0=8bit, 1=16bit +void SignExtend(int rd, int rs, int size) +{ + if (size >= 2) + { + if (rd != rs) + ot(" mov r%d,r%d\n", rd, rs); + return; + } +#if defined(HAVE_ARMv6) && (HAVE_ARMv6) + if (size == 1) + ot(" sxth r%d,r%d ;@ sign extend\n", rd, rs); + else + ot(" sxtb r%d,r%d ;@ sign extend\n", rd, rs); +#else + int shift = size ? 16 : 24; + ot(" mov r%d,r%d,asl #%d\n", rd, rs, shift); + ot(" mov r%d,r%d,asr #%d ;@ sign extend\n", rd, rd, shift); +#endif +} + +void ZeroExtend(int rd, int rs, int size) +{ + if (size >= 2) + { + if (rd != rs) + ot(" mov r%d,r%d\n", rd, rs); + return; + } +#if defined(HAVE_ARMv6) && (HAVE_ARMv6) + if (size == 1) + ot(" uxth r%d,r%d ;@ zero extend\n", rd, rs); + else +#else + if (size == 1) + { + ot(" mov r%d,r%d,lsl #16\n", rd, rs); + ot(" mov r%d,r%d,lsr #16 ;@ zero extend\n", rd, rd); + } + else +#endif + { + ot(" and r%d,r%d,#0xff ;@ zero extend\n", rd, rs); + } +} + // ----------------------------------------------------------------- int g_op; diff --git a/app.h b/app.h index cffd2cb..9d01957 100644 --- a/app.h +++ b/app.h @@ -65,6 +65,8 @@ extern int g_op; extern int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace; int OpGetFlags(int subtract,int xbit,int sprecialz=0); void OpGetFlagsNZ(int rd); +void SignExtend(int rd, int rs, int size); +void ZeroExtend(int rd, int rs, int size); void OpUse(int op,int use); void OpStart(int op,int sea=0,int tea=0,int op_changes_cycles=0,int supervisor_check=0); void OpEnd(int sea=0,int tea=0); diff --git a/config.h b/config.h index d73b5b5..86bd6e0 100644 --- a/config.h +++ b/config.h @@ -5,6 +5,16 @@ **/ +/* + * By default, only ARMv4 instructions are used. + * If you want Cyclone to make use of newer ARM instructions, enable the + * options(s) below. You can also override this using make argument: + * make HAVE_ARMv6=1 + */ +#ifndef HAVE_ARMv6 +#define HAVE_ARMv6 0 +#endif + /* * If this option is enabled, Microsoft ARMASM compatible output is generated * (output file - Cyclone.asm). Otherwise GNU as syntax is used (Cyclone.s). -- 2.39.2