You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(30) |
2
(8) |
3
(5) |
4
(5) |
|
5
(3) |
6
(9) |
7
(5) |
8
(14) |
9
(17) |
10
(27) |
11
(10) |
|
12
(6) |
13
(10) |
14
(7) |
15
(16) |
16
(9) |
17
(14) |
18
(8) |
|
19
(5) |
20
(13) |
21
(21) |
22
(13) |
23
(4) |
24
(1) |
25
(4) |
|
26
(2) |
27
(7) |
28
(4) |
29
(5) |
30
(12) |
|
|
|
From: Crestez D. L. <cdl...@gm...> - 2015-04-14 22:02:51
|
Hello, You seem to be building for mips32, this is wrong. Instead of _mips32_ those object files should all contain "_mips64n32_". You need to make sure your configure target is some form of mips64*, not mips32. What this patch does is add support for the N32 ABI as a secondary arch of mips64. What used to only build valgrind for mips64 will now build a second set of binaries for the N32 ABI. The main valgrind launcher will pick the correct mips64/mips64n32 version of the tool based on flags in the elf header. You also need to avoid including -mabi inside any explicit CFLAGS. Apparently gcc gets confused by multiple -mabi=* flags instead of just using the last option. Maybe you show how you are running the configure script? Also make sure you reran autogen.sh after patching and cleaned any stale binaries. I included the valgrind-developers list because this mail thread should be public in case anyone has similar issues. Regards, Leonard On Wed, Apr 15, 2015 at 12:31 AM, Zhu, Yanwen <Yan...@vi...> wrote: > Leonard, > > > > Thanks for your reply, I just fixed some errors during the patch. You’re > right, not too bad, just 3 files that I had to manually port the changes. > > > > I am building valgrind for MIPS64 with -mabi=n32 using the OCTEOM cross > compiler and I am seeing the following error in the linking phase: > > > > ../coregrind/link_tool_exe_linux 0x38000000 > /home/yzhu/workspace/buildroot/buildroot/output/kg255x.v2_pp_devel/tools/ext/bin/mips64-octeon-linux-gnu-gcc > --sysroot=/home/yzhu/workspace/buildroot/buildroot/output/kg255x.v2_pp_devel/tools > -Os -pipe -Os -mtune=mips64 -mabi=n32 -D_LARGEFILE_SOURCE > -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wl,-melf32btsmipn32 > -march=octeon3 > -I/home/yzhu/workspace/buildroot/buildroot/output/kg255x.v2_pp_devel/toolchain/linux/include > -Wno-long-long -Os -pipe -Os -mtune=mips64 -mabi=n32 -D_LARGEFILE_SOURCE > -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wl,-melf32btsmipn32 > -march=octeon3 -fno-stack-protector -mabi=n32 -Wl,-melf32btsmipn32 > -march=octeon3 > -L/home/yzhu/workspace/buildroot/buildroot/output/kg255x.v2_pp_devel/tools/lib > -L/home/yzhu/workspace/buildroot/buildroot/output/kg255x.v2_pp_devel/tools/usr/lib > -o memcheck-mips32-linux -O2 -g -Wall -Wmissing-prototypes -Wshadow > -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations > -Wno-format-zero-length -fno-strict-aliasing -fno-builtin -O2 -static > -nodefaultlibs -nostartfiles -u __start > memcheck_mips32_linux-mc_leakcheck.o > memcheck_mips32_linux-mc_malloc_wrappers.o memcheck_mips32_linux-mc_main.o > memcheck_mips32_linux-mc_translate.o memcheck_mips32_linux-mc_machine.o > memcheck_mips32_linux-mc_errors.o ../coregrind/libcoregrind-mips32-linux.a > ../VEX/libvex-mips32-linux.a -lgcc > > ../coregrind/libcoregrind-mips32-linux.a(libcoregrind_mips32_linux_a-m_main.o): > In function `__start': > > m_main.c:(.text+0xc): undefined reference to `_gp_disp' > > m_main.c:(.text+0x10): undefined reference to `_gp_disp' > > collect2: error: ld returned 1 exit status > > make[4]: *** [memcheck-mips32-linux] Error 1 > > > > I don’t know what’s going on here, any suggestions? > > > > Thanks, > > Yanwen > > > > *From:* Crestez Dan Leonard [mailto:cdl...@gm...] > *Sent:* Tuesday, April 14, 2015 3:08 PM > *To:* Zhu, Yanwen > *Subject:* Re: Valgrind 13854: Cross compiling for Cavium MIPS64, N32 ABI > > > > Hello, > > > > The patches are against SVN trunk at around the time the patches were > posted (it differs between V1 and V2). Backporting them to 3.10.1 should > not be terribly difficult. They won't apply cleanly but I expect the issues > to be minor and easily solvable. Since the tilegx port was integrated a few > days ago I expect they won't apply cleanly on svn trunk either, at least > not until I rebase and post the next version. > > > > You can also try to compile directly from the git repos mentioned in the > tracker item. That should "just work". > > > > If you have problems compiling you should mention the actual build errors > as well as compiler/target details. Support for N32 should be generic but > I'm only actually targeting octeon chips using the cavium gcc-4.7 toolchain. > > > > Regards, > > Leonard > > > > On Tue, Apr 14, 2015 at 7:16 PM, <Yan...@vi...> wrote: > > Hi Leonard, > > I'm trying to apply your patches for mips64n32 on valgrind 3.10.1 and > there some some errors, I manually fixed the patching errors, however, I > have some problem compiling it. Looks to me that your patches were not > made based on 3.10.1. What version of valgrind were your patches made > from? Do you have patches for 3.10.1? > |
Author: florian
Date: Tue Apr 14 20:59:21 2015
New Revision: 15091
Log:
Followup to r14974. That revision oversimplified a condition, part
of which was presumed to be redundant but wasn't. This caused code
to hang due to an infinite signal-delivery loop. Observed and
tracked down by Austin English.
Added:
trunk/none/tests/x86-linux/hang.c
trunk/none/tests/x86-linux/hang.stderr.exp
trunk/none/tests/x86-linux/hang.vgtest
Modified:
trunk/coregrind/m_signals.c
trunk/none/tests/x86-linux/ (props changed)
trunk/none/tests/x86-linux/Makefile.am
Modified: trunk/coregrind/m_signals.c
==============================================================================
--- trunk/coregrind/m_signals.c (original)
+++ trunk/coregrind/m_signals.c Tue Apr 14 20:59:21 2015
@@ -2427,7 +2427,7 @@
{
Addr fault;
Addr esp;
- NSegment const* seg;
+ NSegment const *seg, *seg_next;
if (info->si_signo != VKI_SIGSEGV)
return False;
@@ -2435,6 +2435,8 @@
fault = (Addr)info->VKI_SIGINFO_si_addr;
esp = VG_(get_SP)(tid);
seg = VG_(am_find_nsegment)(fault);
+ seg_next = seg ? VG_(am_next_nsegment)( seg, True/*fwds*/ )
+ : NULL;
if (VG_(clo_trace_signals)) {
if (seg == NULL)
@@ -2449,6 +2451,10 @@
if (info->si_code == VKI_SEGV_MAPERR
&& seg
+ && seg->kind == SkResvn
+ && seg->smode == SmUpper
+ && seg_next
+ && seg_next->kind == SkAnonC
&& fault >= fault_mask(esp - VG_STACK_REDZONE_SZB)) {
/* If the fault address is above esp but below the current known
stack segment base, and it was a fault because there was
Modified: trunk/none/tests/x86-linux/Makefile.am
==============================================================================
--- trunk/none/tests/x86-linux/Makefile.am (original)
+++ trunk/none/tests/x86-linux/Makefile.am Tue Apr 14 20:59:21 2015
@@ -5,10 +5,12 @@
filter_stderr
EXTRA_DIST = \
+ hang.stderr.exp hang.vgtest \
seg_override.stderr.exp seg_override.stdout.exp seg_override.vgtest \
sigcontext.stdout.exp sigcontext.stderr.exp sigcontext.vgtest
check_PROGRAMS = \
+ hang \
seg_override \
sigcontext
Added: trunk/none/tests/x86-linux/hang.c
==============================================================================
--- trunk/none/tests/x86-linux/hang.c (added)
+++ trunk/none/tests/x86-linux/hang.c Tue Apr 14 20:59:21 2015
@@ -0,0 +1,5 @@
+int main ( void )
+{
+ *(volatile char *)0xDEADBEEF = 'x';
+ return 0;
+}
Added: trunk/none/tests/x86-linux/hang.stderr.exp
==============================================================================
--- trunk/none/tests/x86-linux/hang.stderr.exp (added)
+++ trunk/none/tests/x86-linux/hang.stderr.exp Tue Apr 14 20:59:21 2015
@@ -0,0 +1,9 @@
+
+Process terminating with default action of signal 11 (SIGSEGV)
+ Access not within mapped region at address 0x........
+ at 0x........: main (hang.c:3)
+ If you believe this happened as a result of a stack
+ overflow in your program's main thread (unlikely but
+ possible), you can try to increase the size of the
+ main thread stack using the --main-stacksize= flag.
+ The main thread stack size used in this run was ....
Added: trunk/none/tests/x86-linux/hang.vgtest
==============================================================================
--- trunk/none/tests/x86-linux/hang.vgtest (added)
+++ trunk/none/tests/x86-linux/hang.vgtest Tue Apr 14 20:59:21 2015
@@ -0,0 +1,5 @@
+# r14974 introduced a bug which cause code to hang due to
+# an infinite signal-delivery loop.
+# Can only be reproduced on an x86 box running a 32-bit kernel.
+prog: hang
+vgopts: -q
|
|
From: Philippe W. <phi...@sk...> - 2015-04-14 19:36:40
|
On Mon, 2015-04-13 at 18:39 -0400, Zhi-Gang Liu wrote: > Philippe > > Have you ever tried the patch I post in this mail chain for the TileGX > evCheck issue? > > If works for you I will commit it once I have SVN access. Sorry, I did not had the chance to look at it before. I just tried on an amd64 box. With the patch, the libvexmultiarch_test can properly use tilegx as a host. (of course, I could only test that, nothing of the tilegx behaviour itself). So, whenever you commit this patch, I will cleanup the libvex_test.c code that disables tilegx as host. Thanks Philippe |
|
From: <sv...@va...> - 2015-04-14 19:23:35
|
Author: sewardj
Date: Tue Apr 14 20:23:28 2015
New Revision: 15090
Log:
Add an NCode template for 32-bit loads on 32 bit targets.
Modified:
branches/NCODE/memcheck/mc_include.h
branches/NCODE/memcheck/mc_main.c
branches/NCODE/memcheck/mc_translate.c
Modified: branches/NCODE/memcheck/mc_include.h
==============================================================================
--- branches/NCODE/memcheck/mc_include.h (original)
+++ branches/NCODE/memcheck/mc_include.h Tue Apr 14 20:23:28 2015
@@ -605,6 +605,8 @@
extern NCodeTemplate* MC_(tmpl__LOADV16le_on_64);
extern NCodeTemplate* MC_(tmpl__LOADV8_on_64);
+extern NCodeTemplate* MC_(tmpl__LOADV32le_on_32);
+
/* Helper functions defined in mc_main.c */
Modified: branches/NCODE/memcheck/mc_main.c
==============================================================================
--- branches/NCODE/memcheck/mc_main.c (original)
+++ branches/NCODE/memcheck/mc_main.c Tue Apr 14 20:23:28 2015
@@ -4279,6 +4279,8 @@
VG_REGPARM(1) static ULong mc_LOADV16le_on_64_slow ( Addr a );
VG_REGPARM(1) static ULong mc_LOADV8_on_64_slow ( Addr a );
+VG_REGPARM(1) static UInt mc_LOADV32le_on_32_slow ( Addr a );
+
static void* ncode_alloc ( UInt n ) {
return VG_(malloc)("mc.ncode_alloc (NCode, permanent)", n);
}
@@ -4299,6 +4301,8 @@
NCodeTemplate* MC_(tmpl__LOADV16le_on_64) = NULL;
NCodeTemplate* MC_(tmpl__LOADV8_on_64) = NULL;
+NCodeTemplate* MC_(tmpl__LOADV32le_on_32) = NULL;
+
static NCodeTemplate* mk_tmpl__LOADV64le_on_64 ( NAlloc na )
{
NInstr** hot = na((11+1) * sizeof(NInstr*));
@@ -4609,6 +4613,68 @@
return tmpl;
}
+static NCodeTemplate* mk_tmpl__LOADV32le_on_32 ( NAlloc na )
+{
+ NInstr** hot = na((11+1) * sizeof(NInstr*));
+ NInstr** cold = na((6+1) * sizeof(NInstr*));
+
+ NReg rINVALID = mkNRegINVALID();
+
+ NReg r0 = mkNReg(Nrr_Result, 0);
+ NReg a0 = mkNReg(Nrr_Argument, 0);
+ NReg s0 = mkNReg(Nrr_Scratch, 0);
+
+ /* NCode [r0] = "LOADV32le_on_32" [a0] s0 {
+ hot:
+ 0 tst.w a0, #3 high?
+ 1 bnz cold.4 yes, goto slow path
+ 2 shr.w s0, a0, #16 s0 = pri-map-ix
+ 3 ld.32 s0, [&pri_map[0] + s0 << #2] s0 = sec-map
+ 4 and.w r0, a0, #0xFFFF r0 = sec-map-offB
+ 5 shr.w r0, r0, #2 r0 = sec-map-ix
+ 6 ld.8 r0, [s0 + r0] r0 = sec-map-VABITS8
+ 7 cmp.w r0, #0xAA r0 == VABITS8_DEFINED?
+ 8 bnz cold.0 no, goto cold.0
+ 9 imm.w r0, #0x0 VBITS32_DEFINED
+ 10 nop continue
+ cold:
+ 0 mov.w s0, r0 s0 = sec-map-VABITS8
+ 1 imm.w r0, #0xFFFFFFFF VBITS32_UNDEFINED
+ 2 cmp.w s0, #0x55 s0 == VABITS8_UNDEFINED?
+ 3 bz hot.10 yes, continue
+ 4 call r0 = mc_LOADV32le_on_32_slow[..](a0) call helper
+ 5 b hot.10 continue
+ }
+ */
+ hot[0] = NInstr_SetFlagsWri (na, Nsf_TEST, a0, MASK(4));
+ hot[1] = NInstr_Branch (na, Ncc_NZ, mkNLabel(Nlz_Cold, 4));
+ hot[2] = NInstr_ShiftWri (na, Nsh_SHR, s0, a0, 16);
+ hot[3] = NInstr_LoadU (na, 8, s0, NEA_IRS(na, (HWord)&primary_map[0],
+ s0, 2));
+ hot[4] = NInstr_AluWri (na, Nalu_AND, r0, a0, 0xFFFF);
+ hot[5] = NInstr_ShiftWri (na, Nsh_SHR, r0, r0, 2);
+ hot[6] = NInstr_LoadU (na, 1, r0, NEA_RRS(na, s0, r0, 0));
+ hot[7] = NInstr_SetFlagsWri (na, Nsf_CMP, r0, VA_BITS8_DEFINED);
+ hot[8] = NInstr_Branch (na, Ncc_NZ, mkNLabel(Nlz_Cold, 0));
+ hot[9] = NInstr_ImmW (na, r0, V_BITS32_DEFINED);
+ hot[10] = NInstr_Nop (na);
+
+ cold[0] = NInstr_MovW (na, s0, r0);
+ cold[1] = NInstr_ImmW (na, r0, V_BITS32_UNDEFINED);
+ cold[2] = NInstr_SetFlagsWri (na, Nsf_CMP, s0, VA_BITS8_UNDEFINED);
+ cold[3] = NInstr_Branch (na, Ncc_Z, mkNLabel(Nlz_Hot, 10));
+ cold[4] = NInstr_Call (na, rINVALID, r0, mkNRegVec1(na, a0),
+ (void*)& mc_LOADV32le_on_32_slow,
+ "mc_LOADV32le_on_32_slow");
+ cold[5] = NInstr_Branch (na, Ncc_ALWAYS, mkNLabel(Nlz_Hot, 10));
+
+ hot[11] = cold[6] = NULL;
+ NCodeTemplate* tmpl
+ = mkNCodeTemplate(na,"LOADV32le_on_32",
+ /*res, parms, scratch*/1, 1, 1, hot, cold);
+ return tmpl;
+}
+
void MC_(create_ncode_templates) ( void )
{
@@ -4620,6 +4686,9 @@
MC_(tmpl__LOADV32le_on_64) = mk_tmpl__LOADV32le_on_64(ncode_alloc);
MC_(tmpl__LOADV16le_on_64) = mk_tmpl__LOADV16le_on_64(ncode_alloc);
MC_(tmpl__LOADV8_on_64) = mk_tmpl__LOADV8_on_64(ncode_alloc);
+
+ tl_assert(MC_(tmpl__LOADV32le_on_32) == NULL);
+ MC_(tmpl__LOADV32le_on_32) = mk_tmpl__LOADV32le_on_32(ncode_alloc);
}
@@ -4879,6 +4948,10 @@
{
return mc_LOADVn_slow( a, 32, False/*!isBigEndian*/ );
}
+VG_REGPARM(1) static UInt mc_LOADV32le_on_32_slow ( Addr a )
+{
+ return mc_LOADVn_slow( a, 32, False/*!isBigEndian*/ );
+}
static INLINE
Modified: branches/NCODE/memcheck/mc_translate.c
==============================================================================
--- branches/NCODE/memcheck/mc_translate.c (original)
+++ branches/NCODE/memcheck/mc_translate.c Tue Apr 14 20:23:28 2015
@@ -4625,6 +4625,7 @@
/* ty is now the shadow type for the load. */
/* ------ BEGIN inline NCode ? ------ */
+ /* NCode load cases for 64 bit hosts */
if (guardIsAlwaysTrue(guard) && mce->hWordTy == Ity_I64 && end == Iend_LE) {
switch (ty) {
case Ity_I64: {
@@ -4683,6 +4684,25 @@
break;
}
}
+ else
+ /* NCode load cases for 32 bit hosts */
+ if (guardIsAlwaysTrue(guard) && mce->hWordTy == Ity_I32 && end == Iend_LE) {
+ switch (ty) {
+ case Ity_I32: {
+ /* Unconditional LOAD32le on 32 bit host. Generate inline code. */
+ IRTemp datavbits32 = newTemp(mce, Ity_I32, VSh);
+ NCodeTemplate* tmpl = MC_(tmpl__LOADV32le_on_32);
+ IRAtom** args = mkIRExprVec_1( addrAct );
+ IRTemp* ress = mkIRTempVec_1( datavbits32 );
+ stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
+ return mkexpr(datavbits32);
+ }
+ default:
+ /* else fall through */
+ break;
+ }
+ }
+
/* ------ END inline NCode ? ------ */
/* Now cook up a call to the relevant helper function, to read the
|
Author: sewardj
Date: Tue Apr 14 20:22:04 2015
New Revision: 3129
Log:
Initial arm32-specific infrastructure changes for doing NCode generation.
Most of this is changes to the arm32 assembler (emit_ARMInstr) to use
AssemblerBuffers. No actual NInstr handling yet.
Modified:
branches/NCODE/priv/host_amd64_defs.c
branches/NCODE/priv/host_amd64_defs.h
branches/NCODE/priv/host_arm_defs.c
branches/NCODE/priv/host_arm_defs.h
branches/NCODE/priv/host_generic_reg_alloc2.c
branches/NCODE/priv/host_generic_regs.h
branches/NCODE/priv/main_main.c
branches/NCODE/priv/main_util.h
Modified: branches/NCODE/priv/host_amd64_defs.c
==============================================================================
--- branches/NCODE/priv/host_amd64_defs.c (original)
+++ branches/NCODE/priv/host_amd64_defs.c Tue Apr 14 20:22:04 2015
@@ -2158,7 +2158,7 @@
/* --------- The amd64 assembler (bleh.) --------- */
-#define PUT(_ab, _byte) \
+#define PUT(_ab, _byte) \
do { UInt _off = (_ab)->bufUsed; \
(_ab)->buf[_off] = (_byte); \
(_ab)->bufUsed = _off + 1; \
Modified: branches/NCODE/priv/host_amd64_defs.h
==============================================================================
--- branches/NCODE/priv/host_amd64_defs.h (original)
+++ branches/NCODE/priv/host_amd64_defs.h Tue Apr 14 20:22:04 2015
@@ -838,9 +838,10 @@
extern void getRegUsage_AMD64Instr ( HRegUsage*, const AMD64Instr*, Bool );
extern void mapRegs_AMD64Instr ( HRegRemap*, AMD64Instr*, Bool );
extern Bool isMove_AMD64Instr ( const AMD64Instr*, HReg*, HReg* );
-extern Bool emit_AMD64Instr ( /*MOD*/AssemblyBuffer*,
- const AMD64Instr*, Bool, VexEndness,
- const VexDispatcherAddresses* );
+
+extern Bool emit_AMD64Instr ( /*MOD*/AssemblyBuffer*,
+ const AMD64Instr*, Bool mode64, VexEndness,
+ const VexDispatcherAddresses* );
extern Bool emit_AMD64NCodeBlock ( /*MOD*/AssemblyBuffer* ab_hot,
/*MOD*/AssemblyBuffer* ab_cold,
@@ -856,15 +857,15 @@
extern const RRegUniverse* getRRegUniverse_AMD64 ( void );
-extern HInstrArray* iselSB_AMD64 ( const IRSB*,
- VexArch,
- const VexArchInfo*,
- const VexAbiInfo*,
- Int offs_Host_EvC_Counter,
- Int offs_Host_EvC_FailAddr,
- Bool chainingAllowed,
- Bool addProfInc,
- Addr max_ga );
+extern HInstrArray* iselSB_AMD64 ( const IRSB*,
+ VexArch,
+ const VexArchInfo*,
+ const VexAbiInfo*,
+ Int offs_Host_EvC_Counter,
+ Int offs_Host_EvC_FailAddr,
+ Bool chainingAllowed,
+ Bool addProfInc,
+ Addr max_ga );
/* How big is an event check? This is kind of a kludge because it
depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
Modified: branches/NCODE/priv/host_arm_defs.c
==============================================================================
--- branches/NCODE/priv/host_arm_defs.c (original)
+++ branches/NCODE/priv/host_arm_defs.c Tue Apr 14 20:22:04 2015
@@ -2554,12 +2554,13 @@
condition codes. */
void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
- HReg rreg, Int offsetB, Bool mode64 )
+ HReg rreg, Bool spRel, Int offsetB, Bool mode64 )
{
HRegClass rclass;
vassert(offsetB >= 0);
vassert(!hregIsVirtual(rreg));
vassert(mode64 == False);
+ vassert(!spRel);
*i1 = *i2 = NULL;
rclass = hregClass(rreg);
switch (rclass) {
@@ -2609,12 +2610,13 @@
}
void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
- HReg rreg, Int offsetB, Bool mode64 )
+ HReg rreg, Bool spRel, Int offsetB, Bool mode64 )
{
HRegClass rclass;
vassert(offsetB >= 0);
vassert(!hregIsVirtual(rreg));
vassert(mode64 == False);
+ vassert(!spRel);
*i1 = *i2 = NULL;
rclass = hregClass(rreg);
switch (rclass) {
@@ -2664,6 +2666,17 @@
}
+/* --------- The arm32 assembler (bleh.) --------- */
+
+#define PUT(_ab, _word32) \
+ do { const UInt _off = (_ab)->bufUsed; \
+ (_ab)->buf[_off + 0] = ((_word32) >> 0) & 0xFF; \
+ (_ab)->buf[_off + 1] = ((_word32) >> 8) & 0xFF; \
+ (_ab)->buf[_off + 2] = ((_word32) >> 16) & 0xFF; \
+ (_ab)->buf[_off + 3] = ((_word32) >> 24) & 0xFF; \
+ (_ab)->bufUsed = _off + 4; \
+ } while (0)
+
/* Emit an instruction into buf and return the number of bytes used.
Note that buf is not the insn's final place, and therefore it is
imperative to emit position-independent code. */
@@ -2796,7 +2809,7 @@
/* Get an immediate into a register, using only that
register. (very lame..) */
-static UInt* imm32_to_ireg ( UInt* p, Int rD, UInt imm32 )
+static void imm32_to_ireg ( /*MOD*/AssemblyBuffer* ab, Int rD, UInt imm32 )
{
UInt instr;
vassert(rD >= 0 && rD <= 14); // r15 not good to mess with!
@@ -2805,15 +2818,15 @@
/* mov with a immediate shifter operand of (0, imm32) (??) */
instr = XXXXXX__(X1110,X0011,X1010,X0000,rD,X0000);
instr |= imm32;
- *p++ = instr;
+ PUT(ab, instr);
} else {
// this is very bad; causes Dcache pollution
// ldr rD, [pc]
instr = XXXXX___(X1110,X0101,X1001,X1111,rD);
- *p++ = instr;
+ PUT(ab, instr);
// b .+8
instr = 0xEA000000;
- *p++ = instr;
+ PUT(ab, instr);
// .word imm32
*p++ = imm32;
}
@@ -2826,12 +2839,12 @@
instr = XXXXXXXX(0xE, 0x3, 0x0, (lo16 >> 12) & 0xF, rD,
(lo16 >> 8) & 0xF, (lo16 >> 4) & 0xF,
lo16 & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
if (hi16 != 0) {
instr = XXXXXXXX(0xE, 0x3, 0x4, (hi16 >> 12) & 0xF, rD,
(hi16 >> 8) & 0xF, (hi16 >> 4) & 0xF,
hi16 & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
}
} else {
UInt imm, rot;
@@ -2841,7 +2854,7 @@
imm = imm32 & 0xFF;
rot = 0;
instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
op = X1000;
rN = rD;
}
@@ -2849,7 +2862,7 @@
imm = (imm32 >> 24) & 0xFF;
rot = 4;
instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
op = X1000;
rN = rD;
}
@@ -2857,7 +2870,7 @@
imm = (imm32 >> 16) & 0xFF;
rot = 8;
instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
op = X1000;
rN = rD;
}
@@ -2865,20 +2878,20 @@
imm = (imm32 >> 8) & 0xFF;
rot = 12;
instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
op = X1000;
rN = rD;
}
}
#endif
- return p;
}
/* Get an immediate into a register, using only that register, and
generating exactly 2 instructions, regardless of the value of the
immediate. This is used when generating sections of code that need
to be patched later, so as to guarantee a specific size. */
-static UInt* imm32_to_ireg_EXACTLY2 ( UInt* p, Int rD, UInt imm32 )
+static void imm32_to_ireg_EXACTLY2 ( /*MOD*/AssemblyBuffer* ab,
+ Int rD, UInt imm32 )
{
if (VEX_ARM_ARCHLEVEL(arm_hwcaps) > 6) {
/* Generate movw rD, #low16 ; movt rD, #high16. */
@@ -2888,15 +2901,14 @@
instr = XXXXXXXX(0xE, 0x3, 0x0, (lo16 >> 12) & 0xF, rD,
(lo16 >> 8) & 0xF, (lo16 >> 4) & 0xF,
lo16 & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
instr = XXXXXXXX(0xE, 0x3, 0x4, (hi16 >> 12) & 0xF, rD,
(hi16 >> 8) & 0xF, (hi16 >> 4) & 0xF,
hi16 & 0xF);
- *p++ = instr;
+ PUT(ab, instr);
} else {
vassert(0); /* lose */
}
- return p;
}
/* Check whether p points at a 2-insn sequence cooked up by
@@ -2921,8 +2933,8 @@
}
-static UInt* do_load_or_store32 ( UInt* p,
- Bool isLoad, UInt rD, ARMAMode1* am )
+static void do_load_or_store32 ( /*MOD*/AssemblyBuffer* ab,
+ Bool isLoad, UInt rD, ARMAMode1* am )
{
vassert(rD <= 12);
vassert(am->tag == ARMam1_RI); // RR case is not handled
@@ -2942,29 +2954,26 @@
iregEnc(am->ARMam1.RI.reg),
rD);
instr |= simm12;
- *p++ = instr;
- return p;
+ PUT(ab, instr);
}
-/* Emit an instruction into buf and return the number of bytes used.
- Note that buf is not the insn's final place, and therefore it is
- imperative to emit position-independent code. If the emitted
- instruction was a profiler inc, set *is_profInc to True, else
- leave it unchanged. */
-
-Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
- UChar* buf, Int nbuf, const ARMInstr* i,
- Bool mode64, VexEndness endness_host,
- const void* disp_cp_chain_me_to_slowEP,
- const void* disp_cp_chain_me_to_fastEP,
- const void* disp_cp_xindir,
- const void* disp_cp_xassisted )
+/* Emit an instruction into |ab|. Note that |ab->buf| is not the
+ insn's final place, and therefore it is imperative to emit
+ position-independent code. If the emitted instruction was a
+ profiler inc, return True, else return False. This function must
+ also guarantee to generate 256 or fewer bytes for each instr, so
+ as to facilitate range checking in the caller. */
+
+Bool emit_ARMInstr ( /*MOD*/AssemblyBuffer* ab,
+ const ARMInstr* i,
+ Bool mode64, VexEndness endness_host,
+ const VexDispatcherAddresses* vda )
{
- UInt* p = (UInt*)buf;
- vassert(nbuf >= 32);
+ Bool is_profInc = False;
+ UChar* initialCursor = AssemblyBuffer__getCursor(ab);
vassert(mode64 == False);
- vassert(0 == (((HWord)buf) & 3));
+ vassert(IS_4_ALIGNED(initialCursor));
switch (i->tag) {
case ARMin_Alu: {
@@ -2992,7 +3001,7 @@
|| i->ARMin.Alu.op == ARMalu_SUBS) {
instr |= 1<<20; /* set the S bit */
}
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
case ARMin_Shift: {
@@ -3009,7 +3018,7 @@
instr = skeletal_RI5(argR);
instr |= XXXXX__X(X1110,X0001,X1010,X0000,rD, /* _ _ */ rM);
instr |= (subopc & 3) << 5;
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
case ARMin_Unary: {
@@ -3020,18 +3029,18 @@
case ARMun_CLZ:
instr = XXXXXXXX(X1110,X0001,X0110,X1111,
rDst,X1111,X0001,rSrc);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
case ARMun_NEG: /* RSB rD,rS,#0 */
instr = XXXXX___(X1110,0x2,0x6,rSrc,rDst);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
case ARMun_NOT: {
UInt subopc = X1111; /* MVN */
instr = rSrc;
instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
(subopc << 1) & 0xF, 0, rDst);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
default:
@@ -3046,7 +3055,7 @@
instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
((subopc << 1) & 0xF) | 1,
iregEnc(i->ARMin.CmpOrTst.argL), SBZ );
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
case ARMin_Mov: {
@@ -3056,12 +3065,12 @@
instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
(subopc << 1) & 0xF, SBZ,
iregEnc(i->ARMin.Mov.dst));
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
case ARMin_Imm32: {
- p = imm32_to_ireg( (UInt*)p, iregEnc(i->ARMin.Imm32.dst),
- i->ARMin.Imm32.imm32 );
+ imm32_to_ireg( ab, iregEnc(i->ARMin.Imm32.dst),
+ i->ARMin.Imm32.imm32 );
goto done;
}
case ARMin_LdSt32:
@@ -3099,7 +3108,7 @@
iregEnc(am->ARMam1.RI.reg),
iregEnc(rD));
instr |= simm12;
- *p++ = instr;
+ PUT(ab, instr);
goto done;
} else {
// RR case
@@ -3132,21 +3141,21 @@
// strh
instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,0), iregEnc(rN),
iregEnc(rD), imm8hi, X1011, imm8lo);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
else if (bL == 1 && bS == 0) {
// ldrh
instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregEnc(rN),
iregEnc(rD), imm8hi, X1011, imm8lo);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
else if (bL == 1 && bS == 1) {
// ldrsh
instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregEnc(rN),
iregEnc(rD), imm8hi, X1111, imm8lo);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
else vassert(0); // ill-constructed insn
@@ -3177,7 +3186,7 @@
// ldrsb
instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregEnc(rN),
iregEnc(rD), imm8hi, X1101, imm8lo);
- *p++ = instr;
+ PUT(ab, instr);
goto done;
} else {
// RR case
@@ -3191,8 +3200,8 @@
/* We're generating chain-me requests here, so we need to be
sure this is actually allowed -- no-redir translations
can't use chain-me's. Hence: */
- vassert(disp_cp_chain_me_to_slowEP != NULL);
- vassert(disp_cp_chain_me_to_fastEP != NULL);
+ vassert(vda->disp_cp_chain_me_to_slowEP != NULL);
+ vassert(vda->disp_cp_chain_me_to_fastEP != NULL);
/* Use ptmp for backpatching conditional jumps. */
UInt* ptmp = NULL;
@@ -3202,37 +3211,37 @@
it that we will shortly fill in. */
if (i->ARMin.XDirect.cond != ARMcc_AL) {
vassert(i->ARMin.XDirect.cond != ARMcc_NV);
- ptmp = p;
- *p++ = 0;
+ ptmp = AssemblyBuffer__getCursor_4aligned(ab);
+ PUT(ab, 0);
}
/* Update the guest R15T. */
/* movw r12, lo16(dstGA) */
/* movt r12, hi16(dstGA) */
/* str r12, amR15T */
- p = imm32_to_ireg(p, /*r*/12, i->ARMin.XDirect.dstGA);
- p = do_load_or_store32(p, False/*!isLoad*/,
- /*r*/12, i->ARMin.XDirect.amR15T);
+ imm32_to_ireg(ab, /*r*/12, i->ARMin.XDirect.dstGA);
+ do_load_or_store32(ab, False/*!isLoad*/,
+ /*r*/12, i->ARMin.XDirect.amR15T);
/* --- FIRST PATCHABLE BYTE follows --- */
- /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're
+ /* VG_(vda->disp_cp_chain_me_to_{slowEP,fastEP}) (where we're
calling to) backs up the return address, so as to find the
address of the first patchable byte. So: don't change the
number of instructions (3) below. */
- /* movw r12, lo16(VG_(disp_cp_chain_me_to_{slowEP,fastEP})) */
- /* movt r12, hi16(VG_(disp_cp_chain_me_to_{slowEP,fastEP})) */
+ /* movw r12, lo16(vda->disp_cp_chain_me_to_{slowEP,fastEP}) */
+ /* movt r12, hi16(vda->disp_cp_chain_me_to_{slowEP,fastEP}) */
/* blx r12 (A1) */
const void* disp_cp_chain_me
- = i->ARMin.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP
- : disp_cp_chain_me_to_slowEP;
- p = imm32_to_ireg_EXACTLY2(p, /*r*/12,
- (UInt)(Addr)disp_cp_chain_me);
- *p++ = 0xE12FFF3C;
+ = i->ARMin.XDirect.toFastEP ? vda->disp_cp_chain_me_to_fastEP
+ : vda->disp_cp_chain_me_to_slowEP;
+ imm32_to_ireg_EXACTLY2(ab, /*r*/12, (UInt)(Addr)disp_cp_chain_me);
+ PUT(ab, 0xE12FFF3C);
/* --- END of PATCHABLE BYTES --- */
/* Fix up the conditional jump, if there was one. */
if (i->ARMin.XDirect.cond != ARMcc_AL) {
- Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
+ /* |delta| must be signed */
+ Int delta = AssemblyBuffer__getCursor(ab) - (UChar*)ptmp;
vassert(delta > 0 && delta < 40);
vassert((delta & 3) == 0);
UInt notCond = 1 ^ (UInt)i->ARMin.XDirect.cond;
@@ -3250,7 +3259,7 @@
translations without going through the scheduler. That
means no XDirects or XIndirs out from no-redir
translations. Hence: */
- vassert(disp_cp_xindir != NULL);
+ vassert(vda->disp_cp_xindir != NULL);
/* Use ptmp for backpatching conditional jumps. */
UInt* ptmp = NULL;
@@ -3260,25 +3269,26 @@
it that we will shortly fill in. */
if (i->ARMin.XIndir.cond != ARMcc_AL) {
vassert(i->ARMin.XIndir.cond != ARMcc_NV);
- ptmp = p;
- *p++ = 0;
+ ptmp = AssemblyBuffer__getCursor_4aligned(ab);
+ PUT(ab, 0);
}
/* Update the guest R15T. */
/* str r-dstGA, amR15T */
- p = do_load_or_store32(p, False/*!isLoad*/,
- iregEnc(i->ARMin.XIndir.dstGA),
- i->ARMin.XIndir.amR15T);
+ do_load_or_store32(ab, False/*!isLoad*/,
+ iregEnc(i->ARMin.XIndir.dstGA),
+ i->ARMin.XIndir.amR15T);
- /* movw r12, lo16(VG_(disp_cp_xindir)) */
- /* movt r12, hi16(VG_(disp_cp_xindir)) */
+ /* movw r12, lo16(vda->disp_cp_xindir) */
+ /* movt r12, hi16(vda->disp_cp_xindir) */
/* bx r12 (A1) */
- p = imm32_to_ireg(p, /*r*/12, (UInt)(Addr)disp_cp_xindir);
- *p++ = 0xE12FFF1C;
+ imm32_to_ireg(ab, /*r*/12, (UInt)(Addr)vda->disp_cp_xindir);
+ PUT(ab, 0xE12FFF1C);
/* Fix up the conditional jump, if there was one. */
if (i->ARMin.XIndir.cond != ARMcc_AL) {
- Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
+ /* |delta| must be signed */
+ Int delta = AssemblyBuffer__getCursor(ab) - (UChar*)ptmp;
vassert(delta > 0 && delta < 40);
vassert((delta & 3) == 0);
UInt notCond = 1 ^ (UInt)i->ARMin.XIndir.cond;
@@ -3298,15 +3308,15 @@
it that we will shortly fill in. */
if (i->ARMin.XAssisted.cond != ARMcc_AL) {
vassert(i->ARMin.XAssisted.cond != ARMcc_NV);
- ptmp = p;
- *p++ = 0;
+ ptmp = AssemblyBuffer__getCursor_4aligned(ab);
+ PUT(ab, 0);
}
/* Update the guest R15T. */
/* str r-dstGA, amR15T */
- p = do_load_or_store32(p, False/*!isLoad*/,
- iregEnc(i->ARMin.XAssisted.dstGA),
- i->ARMin.XAssisted.amR15T);
+ do_load_or_store32(ab, False/*!isLoad*/,
+ iregEnc(i->ARMin.XAssisted.dstGA),
+ i->ARMin.XAssisted.amR15T);
/* movw r8, $magic_number */
UInt trcval = 0;
@@ -3332,17 +3342,18 @@
vpanic("emit_ARMInstr.ARMin_XAssisted: unexpected jump kind");
}
vassert(trcval != 0);
- p = imm32_to_ireg(p, /*r*/8, trcval);
+ imm32_to_ireg(ab, /*r*/8, trcval);
- /* movw r12, lo16(VG_(disp_cp_xassisted)) */
- /* movt r12, hi16(VG_(disp_cp_xassisted)) */
+ /* movw r12, lo16(vda->disp_cp_xassisted) */
+ /* movt r12, hi16(vda->disp_cp_xassisted) */
/* bx r12 (A1) */
- p = imm32_to_ireg(p, /*r*/12, (UInt)(Addr)disp_cp_xassisted);
- *p++ = 0xE12FFF1C;
+ imm32_to_ireg(ab, /*r*/12, (UInt)(Addr)vda->disp_cp_xassisted);
+ PUT(ab, 0xE12FFF1C);
/* Fix up the conditional jump, if there was one. */
if (i->ARMin.XAssisted.cond != ARMcc_AL) {
- Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
+ /* |delta| must be signed */
+ Int delta = AssemblyBuffer__getCursor(ab) - (UChar*)ptmp;
vassert(delta > 0 && delta < 40);
vassert((delta & 3) == 0);
UInt notCond = 1 ^ (UInt)i->ARMin.XAssisted.cond;
@@ -3360,7 +3371,7 @@
instr |= XXXXX___(i->ARMin.CMov.cond, (1 & (subopc >> 3)),
(subopc << 1) & 0xF, SBZ,
iregEnc(i->ARMin.CMov.dst));
- *p++ = instr;
+ PUT(ab, instr);
goto done;
}
@@ -3383,13 +3394,12 @@
if (i->ARMin.Call.cond == ARMcc_AL/*call always happens*/
|| i->ARMin.Call.rloc.pri == RLPri_None/*no fixup action*/) {
// r"scratchNo" = &target
- p = imm32_to_ireg( (UInt*)p,
- scratchNo, (UInt)i->ARMin.Call.target );
+ imm32_to_ireg( ab, scratchNo, (UInt)i->ARMin.Call.target );
// blx{cond} r"scratchNo"
instr = XXX___XX(i->ARMin.Call.cond, X0001, X0010, /*___*/
X0011, scratchNo);
instr |= 0xFFF << 8; // stick in the SBOnes
- *p++ = instr;
+ PUT(ab, instr);
} else {
Int delta;
/* Complex case. We have to generate an if-then-else
@@ -3406,29 +3416,29 @@
// after:
// before:
- UInt* pBefore = p;
+ UInt* pBefore = AssemblyBuffer__getCursor_4aligned(ab);
// b{!cond} else: // ptmp1 points here
- *p++ = 0; // filled in later
+ PUT(ab, 0); // filled in later
// r"scratchNo" = &target
- p = imm32_to_ireg( (UInt*)p,
- scratchNo, (UInt)i->ARMin.Call.target );
+ imm32_to_ireg( ab, scratchNo, (UInt)i->ARMin.Call.target );
// blx{AL} r"scratchNo"
instr = XXX___XX(ARMcc_AL, X0001, X0010, /*___*/
X0011, scratchNo);
instr |= 0xFFF << 8; // stick in the SBOnes
- *p++ = instr;
+ PUT(ab, instr);
// preElse:
- UInt* pPreElse = p;
+ UInt* pPreElse = AssemblyBuffer__getCursor_4aligned(ab);
// b after:
- *p++ = 0; // filled in later
+ PUT(ab, 0); // filled in later
// else:
- delta = (UChar*)p - (UChar*)pBefore;
+ delta = AssemblyBuffer__getCursor(ab) - (UChar*)pBefore;
+ vassert(IS_4_ALIGNED(delta));
delta = (delta >> 2) - 2;
*pBefore
= XX______(1 ^ i->ARMin.Call.cond, X1010) | (delta & 0xFFFFFF);
@@ -3436,20 +3446,21 @@
/* Do the 'else' actions */
switch (i->ARMin.Call.rloc.pri) {
case RLPri_Int:
- p = imm32_to_ireg_EXACTLY2(p, /*r*/0, 0x55555555);
+ imm32_to_ireg_EXACTLY2(ab, /*r*/0, 0x55555555);
break;
case RLPri_2Int:
vassert(0); //ATC
- p = imm32_to_ireg_EXACTLY2(p, /*r*/0, 0x55555555);
+ imm32_to_ireg_EXACTLY2(ab, /*r*/0, 0x55555555);
/* mov r1, r0 */
- *p++ = 0xE1A01000;
+ PUT(ab, 0xE1A01000);
break;
case RLPri_None: case RLPri_INVALID: default:
vassert(0);
}
// after:
- delta = (UChar*)p - (UChar*)pPreElse;
+ delta = AssemblyBuffer__getCursor(ab) - (UChar*)pPreElse;
+ vassert(IS_4_ALIGNED(delta));
delta = (delta >> 2) - 2;
*pPreElse = XX______(ARMcc_AL, X1010) | (delta & 0xFFFFFF);
}
@@ -3463,9 +3474,9 @@
E0C10392 smull r0(LO), r1(HI), r2, r3
*/
switch (i->ARMin.Mul.op) {
- case ARMmul_PLAIN: *p++ = 0xE0000392; goto done;
- case ARMmul_ZX: *p++ = 0xE0810392; goto done;
- case ARMmul_SX: *p++ = 0xE0C10392; goto done;
+ case ARMmul_PLAIN: PUT(ab, 0xE0000392); goto done;
+ case ARMmul_ZX: PUT(ab, 0xE0810392); goto done;
+ case ARMmul_SX: PUT(ab, 0xE0C10392); goto done;
default: vassert(0);
}
goto bad;
@@ -3477,10 +3488,10 @@
E1B42F9F ldrexd r2, r3, [r4]
*/
switch (i->ARMin.LdrEX.szB) {
- case 1: *p++ = 0xE1D42F9F; goto done;
- case 2: *p++ = 0xE1F42F9F; goto done;
- case 4: *p++ = 0xE1942F9F; goto done;
- case 8: *p++ = 0xE1B42F9F; goto done;
+ case 1: PUT(ab, 0xE1D42F9F); goto done;
+ case 2: PUT(ab, 0xE1F42F9F); goto done;
+ case 4: PUT(ab, 0xE1942F9F); goto done;
+ case 8: PUT(ab, 0xE1B42F9F); goto done;
default: break;
}
goto bad;
@@ -3492,10 +3503,10 @@
E1A40F92 strexd r0, r2, r3, [r4]
*/
switch (i->ARMin.StrEX.szB) {
- case 1: *p++ = 0xE1C40F92; goto done;
- case 2: *p++ = 0xE1E40F92; goto done;
- case 4: *p++ = 0xE1840F92; goto done;
- case 8: *p++ = 0xE1A40F92; goto done;
+ case 1: PUT(ab, 0xE1C40F92); goto done;
+ case 2: PUT(ab, 0xE1E40F92); goto done;
+ case 4: PUT(ab, 0xE1840F92); goto done;
+ case 8: PUT(ab, 0xE1A40F92); goto done;
default: break;
}
goto bad;
@@ -3513,7 +3524,7 @@
vassert(0 == (off8 & 0xFFFFFF00));
insn = XXXXXX__(0xE,X1101,BITS4(bU,0,0,bL),rN,dD,X1011);
insn |= off8;
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VLdStS: {
@@ -3530,7 +3541,7 @@
vassert(0 == (off8 & 0xFFFFFF00));
insn = XXXXXX__(0xE,X1101,BITS4(bU,bD,0,bL),rN, (fD >> 1), X1010);
insn |= off8;
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VAluD: {
@@ -3552,7 +3563,7 @@
UInt bS = (pqrs >> 0) & 1;
UInt insn = XXXXXXXX(0xE, X1110, BITS4(bP,0,bQ,bR), dN, dD,
X1011, BITS4(0,bS,0,0), dM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VAluS: {
@@ -3578,7 +3589,7 @@
UInt insn = XXXXXXXX(0xE, X1110, BITS4(bP,bD,bQ,bR),
(dN >> 1), (dD >> 1),
X1010, BITS4(bN,bS,bM,0), (dM >> 1));
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VUnaryD: {
@@ -3601,7 +3612,7 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VUnaryS: {
@@ -3632,15 +3643,15 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VCmpD: {
UInt dD = dregEnc(i->ARMin.VCmpD.argL);
UInt dM = dregEnc(i->ARMin.VCmpD.argR);
UInt insn = XXXXXXXX(0xE, X1110, X1011, X0100, dD, X1011, X0100, dM);
- *p++ = insn; /* FCMPD dD, dM */
- *p++ = 0xEEF1FA10; /* FMSTAT */
+ PUT(ab, insn); /* FCMPD dD, dM */
+ PUT(ab, 0xEEF1FA10); /* FMSTAT */
goto done;
}
case ARMin_VCMovD: {
@@ -3649,7 +3660,7 @@
UInt dM = dregEnc(i->ARMin.VCMovD.src);
vassert(cc < 16 && cc != ARMcc_AL);
UInt insn = XXXXXXXX(cc, X1110,X1011,X0000,dD,X1011,X0100,dM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VCMovS: {
@@ -3660,7 +3671,7 @@
UInt insn = XXXXXXXX(cc, X1110, BITS4(1,(fD & 1),1,1),
X0000,(fD >> 1),X1010,
BITS4(0,1,(fM & 1),0), (fM >> 1));
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VCvtSD: {
@@ -3670,7 +3681,7 @@
UInt insn = XXXXXXXX(0xE, X1110, X1011, X0111, dD, X1010,
BITS4(1,1, (fM & 1), 0),
(fM >> 1));
- *p++ = insn;
+ PUT(ab, insn);
goto done;
} else {
UInt fD = fregEnc(i->ARMin.VCvtSD.dst);
@@ -3678,7 +3689,7 @@
UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1),
X0111, (fD >> 1),
X1011, X1100, dM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
}
@@ -3695,7 +3706,7 @@
= XXXXXXXX(0xE, 0xC, i->ARMin.VXferD.toD ? 4 : 5,
rHi, rLo, 0xB,
BITS4(0,0, ((dD >> 4) & 1), 1), (dD & 0xF));
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VXferS: {
@@ -3710,7 +3721,7 @@
= XXXXXXXX(0xE, 0xE, i->ARMin.VXferS.toS ? 0 : 1,
(fD >> 1) & 0xF, rLo, 0xA,
BITS4((fD & 1),0,0,1), 0);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_VCvtID: {
@@ -3723,7 +3734,7 @@
UInt insn = XXXXXXXX(0xE, X1110, X1011, X1000, regD,
X1011, BITS4(1,1,(regF & 1),0),
(regF >> 1) & 0xF);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
if (iToD && (!syned)) {
@@ -3733,7 +3744,7 @@
UInt insn = XXXXXXXX(0xE, X1110, X1011, X1000, regD,
X1011, BITS4(0,1,(regF & 1),0),
(regF >> 1) & 0xF);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
if ((!iToD) && syned) {
@@ -3743,7 +3754,7 @@
UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(regF & 1),1,1),
X1101, (regF >> 1) & 0xF,
X1011, X0100, regD);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
if ((!iToD) && (!syned)) {
@@ -3753,7 +3764,7 @@
UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(regF & 1),1,1),
X1100, (regF >> 1) & 0xF,
X1011, X0100, regD);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
/*UNREACHED*/
@@ -3764,7 +3775,7 @@
UInt iReg = iregEnc(i->ARMin.FPSCR.iReg);
if (toFPSCR) {
/* fmxr fpscr, iReg is EEE1 iReg A10 */
- *p++ = 0xEEE10A10 | ((iReg & 0xF) << 12);
+ PUT(ab, 0xEEE10A10 | ((iReg & 0xF) << 12));
goto done;
}
goto bad; // FPSCR -> iReg case currently ATC
@@ -3773,16 +3784,16 @@
// It's not clear (to me) how these relate to the ARMv7
// versions, so let's just use the v7 versions as they
// are at least well documented.
- //*p++ = 0xEE070F9A; /* mcr 15,0,r0,c7,c10,4 (DSB) */
- //*p++ = 0xEE070FBA; /* mcr 15,0,r0,c7,c10,5 (DMB) */
- //*p++ = 0xEE070F95; /* mcr 15,0,r0,c7,c5,4 (ISB) */
- *p++ = 0xF57FF04F; /* DSB sy */
- *p++ = 0xF57FF05F; /* DMB sy */
- *p++ = 0xF57FF06F; /* ISB */
+ //PUT(ab, 0xEE070F9A); /* mcr 15,0,r0,c7,c10,4 (DSB) */
+ //PUT(ab, 0xEE070FBA); /* mcr 15,0,r0,c7,c10,5 (DMB) */
+ //PUT(ab, 0xEE070F95); /* mcr 15,0,r0,c7,c5,4 (ISB) */
+ PUT(ab, 0xF57FF04F); /* DSB sy */
+ PUT(ab, 0xF57FF05F); /* DMB sy */
+ PUT(ab, 0xF57FF06F); /* ISB */
goto done;
}
case ARMin_CLREX: {
- *p++ = 0xF57FF01F; /* clrex */
+ PUT(ab, 0xF57FF01F); /* clrex */
goto done;
}
@@ -3803,7 +3814,7 @@
}
insn = XXXXXXXX(0xF, X0100, BITS4(0, D, bL, 0),
regN, regD, X1010, X1000, regM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NLdStD: {
@@ -3823,7 +3834,7 @@
}
insn = XXXXXXXX(0xF, X0100, BITS4(0, D, bL, 0),
regN, regD, X0111, X1000, regM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NUnaryS: {
@@ -3854,7 +3865,7 @@
insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1),
(i->ARMin.NUnaryS.size & 0xf), regD,
X1100, BITS4(0,Q,M,0), regM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
case ARMneon_SETELEM:
regD = Q ? (qregEnc(i->ARMin.NUnaryS.dst->reg) << 1) :
@@ -3890,7 +3901,7 @@
insn = XXXXXXXX(0xE, X1110, BITS4(0,(opc1 >> 1),(opc1 & 1),0),
regD, regM, X1011,
BITS4(D,(opc2 >> 1),(opc2 & 1),1), X0000);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
case ARMneon_GETELEMU:
regM = Q ? (qregEnc(i->ARMin.NUnaryS.src->reg) << 1) :
@@ -3931,7 +3942,7 @@
insn = XXXXXXXX(0xE, X1110, BITS4(1,(opc1 >> 1),(opc1 & 1),1),
regM, regD, X1011,
BITS4(M,(opc2 >> 1),(opc2 & 1),1), X0000);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
case ARMneon_GETELEMS:
regM = Q ? (qregEnc(i->ARMin.NUnaryS.src->reg) << 1) :
@@ -3979,7 +3990,7 @@
insn = XXXXXXXX(0xE, X1110, BITS4(0,(opc1 >> 1),(opc1 & 1),1),
regM, regD, X1011,
BITS4(M,(opc2 >> 1),(opc2 & 1),1), X0000);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
default:
goto bad;
@@ -4198,7 +4209,7 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NDual: {
@@ -4232,7 +4243,7 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NBinary: {
@@ -4458,7 +4469,7 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NShift: {
@@ -4501,7 +4512,7 @@
default:
goto bad;
}
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NShl64: {
@@ -4521,7 +4532,7 @@
UInt Vm = regM & 0xF;
UInt insn = XXXXXXXX(X1111,X0010, BITS4(1,D,(amt>>5)&1,(amt>>4)&1),
amt & 0xF, Vd, X0101, BITS4(L,Q,M,1), Vm);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NeonImm: {
@@ -4569,7 +4580,7 @@
}
insn = XXXXXXXX(0xF, BITS4(0,0,1,j), BITS4(1,D,0,0), imm3, regD,
cmode, BITS4(0,Q,op,1), imm4);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_NCMovQ: {
@@ -4583,11 +4594,11 @@
vassert(cc < 16 && cc != ARMcc_AL && cc != ARMcc_NV);
/* b!cc here+8: !cc A00 0000 */
UInt insn = XXXXXXXX(cc ^ 1, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
- *p++ = insn;
+ PUT(ab, insn);
/* vmov qD, qM */
insn = XXXXXXXX(0xF, 0x2, BITS4(0,D,1,0),
vM, vD, BITS4(0,0,0,1), BITS4(M,1,M,1), vM);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
case ARMin_Add32: {
@@ -4596,10 +4607,10 @@
UInt imm32 = i->ARMin.Add32.imm32;
vassert(regD != regN);
/* MOV regD, imm32 */
- p = imm32_to_ireg((UInt *)p, regD, imm32);
+ imm32_to_ireg(ab, regD, imm32);
/* ADD regD, regN, regD */
UInt insn = XXXXXXXX(0xE, 0, X1000, regN, regD, 0, 0, regD);
- *p++ = insn;
+ PUT(ab, insn);
goto done;
}
@@ -4613,20 +4624,21 @@
bx r12
nofail:
*/
- UInt* p0 = p;
- p = do_load_or_store32(p, True/*isLoad*/, /*r*/12,
- i->ARMin.EvCheck.amCounter);
- *p++ = 0xE25CC001; /* subs r12, r12, #1 */
- p = do_load_or_store32(p, False/*!isLoad*/, /*r*/12,
- i->ARMin.EvCheck.amCounter);
- *p++ = 0x5A000001; /* bpl nofail */
- p = do_load_or_store32(p, True/*isLoad*/, /*r*/12,
- i->ARMin.EvCheck.amFailAddr);
- *p++ = 0xE12FFF1C; /* bx r12 */
+ UInt* p0 = AssemblyBuffer__getCursor_4aligned(ab);
+ do_load_or_store32(ab, True/*isLoad*/, /*r*/12,
+ i->ARMin.EvCheck.amCounter);
+ PUT(ab, 0xE25CC001); /* subs r12, r12, #1 */
+ do_load_or_store32(ab, False/*!isLoad*/, /*r*/12,
+ i->ARMin.EvCheck.amCounter);
+ PUT(ab, 0x5A000001); /* bpl nofail */
+ do_load_or_store32(ab, True/*isLoad*/, /*r*/12,
+ i->ARMin.EvCheck.amFailAddr);
+ PUT(ab, 0xE12FFF1C); /* bx r12 */
/* nofail: */
/* Crosscheck */
- vassert(evCheckSzB_ARM() == (UChar*)p - (UChar*)p0);
+ vassert(evCheckSzB_ARM()
+ == (UChar*)AssemblyBuffer__getCursor(ab) - (UChar*)p0);
goto done;
}
@@ -4645,16 +4657,16 @@
adc r11, r11, #0
str r11, [r12+4]
*/
- p = imm32_to_ireg_EXACTLY2(p, /*r*/12, 0x65556555);
- *p++ = 0xE59CB000;
- *p++ = 0xE29BB001;
- *p++ = 0xE58CB000;
- *p++ = 0xE59CB004;
- *p++ = 0xE2ABB000;
- *p++ = 0xE58CB004;
+ imm32_to_ireg_EXACTLY2(ab, /*r*/12, 0x65556555);
+ PUT(ab, 0xE59CB000);
+ PUT(ab, 0xE29BB001);
+ PUT(ab, 0xE58CB000);
+ PUT(ab, 0xE59CB004);
+ PUT(ab, 0xE2ABB000);
+ PUT(ab, 0xE58CB004);
/* Tell the caller .. */
- vassert(!(*is_profInc));
- *is_profInc = True;
+ vassert(!is_profInc);
+ is_profInc = True;
goto done;
}
@@ -4669,11 +4681,13 @@
/*NOTREACHED*/
done:
- vassert(((UChar*)p) - &buf[0] <= 32);
- return ((UChar*)p) - &buf[0];
+ vassert(AssemblyBuffer__getCursor(ab) - initialCursor <= 32);
+ return is_profInc;
}
+/* --------- Helpers for translation chaining. --------- */
+
/* How big is an event check? See case for ARMin_EvCheck in
emit_ARMInstr just above. That crosschecks what this returns, so
we can tell if we're inconsistent. */
@@ -4756,9 +4770,11 @@
p[1] = 0xFF000000;
p[2] = 0xFF000000;
} else {
- (void)imm32_to_ireg_EXACTLY2(
- p, /*r*/12, (UInt)(Addr)place_to_jump_to);
- p[2] = 0xE12FFF1C;
+ AssemblyBuffer ab;
+ AssemblyBuffer__init(&ab, (UChar*)p, 12);
+ imm32_to_ireg_EXACTLY2(&ab, /*r*/12, (UInt)(Addr)place_to_jump_to);
+ PUT(&ab, 0xE12FFF1C);
+ vassert(AssemblyBuffer__getRemainingSize(&ab) == 0);
}
VexInvalRange vir = {(HWord)p, 12};
@@ -4822,9 +4838,11 @@
<8 bytes generated by imm32_to_ireg_EXACTLY2>
E1 2F FF 3C
*/
- (void)imm32_to_ireg_EXACTLY2(
- p, /*r*/12, (UInt)(Addr)disp_cp_chain_me);
- p[2] = 0xE12FFF3C;
+ AssemblyBuffer ab;
+ AssemblyBuffer__init(&ab, (UChar*)p, 12);
+ imm32_to_ireg_EXACTLY2(&ab, /*r*/12, (UInt)(Addr)disp_cp_chain_me);
+ PUT(&ab, 0xE12FFF3C);
+ vassert(AssemblyBuffer__getRemainingSize(&ab) == 0);
VexInvalRange vir = {(HWord)p, 12};
return vir;
}
@@ -4847,12 +4865,16 @@
vassert(p[5] == 0xE59CB004);
vassert(p[6] == 0xE2ABB000);
vassert(p[7] == 0xE58CB004);
- imm32_to_ireg_EXACTLY2(p, /*r*/12, (UInt)(Addr)location_of_counter);
+ AssemblyBuffer ab;
+ AssemblyBuffer__init(&ab, (UChar*)p, 8);
+ imm32_to_ireg_EXACTLY2(&ab, /*r*/12, (UInt)(Addr)location_of_counter);
+ vassert(AssemblyBuffer__getRemainingSize(&ab) == 0);
VexInvalRange vir = {(HWord)p, 8};
return vir;
}
+#undef PUT
#undef BITS4
#undef X0000
#undef X0001
Modified: branches/NCODE/priv/host_arm_defs.h
==============================================================================
--- branches/NCODE/priv/host_arm_defs.h (original)
+++ branches/NCODE/priv/host_arm_defs.h Tue Apr 14 20:22:04 2015
@@ -1027,31 +1027,28 @@
extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
extern Bool isMove_ARMInstr ( const ARMInstr*, HReg*, HReg* );
-extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
- UChar* buf, Int nbuf, const ARMInstr* i,
- Bool mode64,
- VexEndness endness_host,
- const void* disp_cp_chain_me_to_slowEP,
- const void* disp_cp_chain_me_to_fastEP,
- const void* disp_cp_xindir,
- const void* disp_cp_xassisted );
+
+extern Bool emit_ARMInstr ( /*MOD*/AssemblyBuffer* ab,
+ const ARMInstr* i,
+ Bool mode64, VexEndness endness_host,
+ const VexDispatcherAddresses* vda );
extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
- HReg rreg, Int offset, Bool );
+ HReg rreg, Bool spRel, Int offset, Bool );
extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
- HReg rreg, Int offset, Bool );
+ HReg rreg, Bool spRel, Int offset, Bool );
extern const RRegUniverse* getRRegUniverse_ARM ( void );
-extern HInstrArray* iselSB_ARM ( const IRSB*,
- VexArch,
- const VexArchInfo*,
- const VexAbiInfo*,
- Int offs_Host_EvC_Counter,
- Int offs_Host_EvC_FailAddr,
- Bool chainingAllowed,
- Bool addProfInc,
- Addr max_ga );
+extern HInstrArray* iselSB_ARM ( const IRSB*,
+ VexArch,
+ const VexArchInfo*,
+ const VexAbiInfo*,
+ Int offs_Host_EvC_Counter,
+ Int offs_Host_EvC_FailAddr,
+ Bool chainingAllowed,
+ Bool addProfInc,
+ Addr max_ga );
/* How big is an event check? This is kind of a kludge because it
depends on the offsets of host_EvC_FAILADDR and
Modified: branches/NCODE/priv/host_generic_reg_alloc2.c
==============================================================================
--- branches/NCODE/priv/host_generic_reg_alloc2.c (original)
+++ branches/NCODE/priv/host_generic_reg_alloc2.c Tue Apr 14 20:22:04 2015
@@ -301,8 +301,6 @@
/* Vectorised memset, copied from Valgrind's m_libcbase.c. */
static void* local_memset ( void *destV, Int c, SizeT sz )
{
-# define IS_4_ALIGNED(aaa_p) (0 == (((HWord)(aaa_p)) & ((HWord)0x3)))
-
UInt c4;
UChar* d = destV;
UChar uc = c;
@@ -336,8 +334,6 @@
sz--;
}
return destV;
-
-# undef IS_4_ALIGNED
}
Modified: branches/NCODE/priv/host_generic_regs.h
==============================================================================
--- branches/NCODE/priv/host_generic_regs.h (original)
+++ branches/NCODE/priv/host_generic_regs.h Tue Apr 14 20:22:04 2015
@@ -537,6 +537,16 @@
return &abuf->buf[abuf->bufUsed];
}
+static inline UInt* AssemblyBuffer__getCursor_4aligned ( const
+ AssemblyBuffer* abuf )
+{
+ UChar* addr = &abuf->buf[abuf->bufUsed];
+ vassert(IS_4_ALIGNED(addr));
+ /* Cast via HWord so that gcc on arm32 doesn't complain about the
+ increase of alignment requirements. */
+ return (UInt*)(HWord)addr;
+}
+
static inline UInt AssemblyBuffer__getNext ( const AssemblyBuffer* abuf )
{
return abuf->bufUsed;
Modified: branches/NCODE/priv/main_main.c
==============================================================================
--- branches/NCODE/priv/main_main.c (original)
+++ branches/NCODE/priv/main_main.c Tue Apr 14 20:22:04 2015
@@ -545,7 +545,7 @@
host_word_type = Ity_I64;
vassert(vta->archinfo_host.endness == VexEndnessBE);
break;
-
+#endif
case VexArchARM:
mode64 = False;
rRegUniv = ARMFN(getRRegUniverse_ARM());
@@ -562,7 +562,7 @@
host_word_type = Ity_I32;
vassert(vta->archinfo_host.endness == VexEndnessLE);
break;
-
+#if 0
case VexArchARM64:
mode64 = True;
rRegUniv = ARM64FN(getRRegUniverse_ARM64());
@@ -732,7 +732,7 @@
vassert(sizeof( ((VexGuestS390XState*)0)->guest_CMLEN ) == 8);
vassert(sizeof( ((VexGuestS390XState*)0)->guest_NRADDR ) == 8);
break;
-
+#endif
case VexArchARM:
preciseMemExnsFn
= ARMFN(guest_arm_state_requires_precise_mem_exns);
@@ -753,7 +753,7 @@
vassert(sizeof( ((VexGuestARMState*)0)->guest_CMLEN ) == 4);
vassert(sizeof( ((VexGuestARMState*)0)->guest_NRADDR ) == 4);
break;
-
+#if 0
case VexArchARM64:
preciseMemExnsFn
= ARM64FN(guest_arm64_state_requires_precise_mem_exns);
@@ -1214,7 +1214,8 @@
(see comment on definition of type Relocation) */
vassert(rl->rshift <= 2);
Long E =
- ((Long)(ULong)dst) + ((Long)rl->bias) - ((Long)(ULong)where);
+ ((Long)(ULong)(HWord)dst) + ((Long)rl->bias)
+ - ((Long)(ULong)(HWord)where);
E = E >>/*signed*/rl->rshift;
if (debug_reloc)
vex_printf("E = 0x%llx\n", E);
Modified: branches/NCODE/priv/main_util.h
==============================================================================
--- branches/NCODE/priv/main_util.h (original)
+++ branches/NCODE/priv/main_util.h Tue Apr 14 20:22:04 2015
@@ -50,6 +50,8 @@
# define offsetof(type,memb) ((SizeT)(HWord)&((type*)0)->memb)
#endif
+#define IS_4_ALIGNED(_addr) (0 == (((HWord)(_addr)) & ((HWord)0x3)))
+
// Poor man's static assert
#define STATIC_ASSERT(x) extern int vex__unused_array[(x) ? 1 : -1] \
__attribute__((unused))
|
|
From: <sv...@va...> - 2015-04-14 18:35:46
|
Author: sewardj
Date: Tue Apr 14 19:35:38 2015
New Revision: 15089
Log:
Add an NCode template for 16 bit loads on 64 bit targets.
Modified:
branches/NCODE/memcheck/mc_include.h
branches/NCODE/memcheck/mc_main.c
branches/NCODE/memcheck/mc_translate.c
Modified: branches/NCODE/memcheck/mc_include.h
==============================================================================
--- branches/NCODE/memcheck/mc_include.h (original)
+++ branches/NCODE/memcheck/mc_include.h Tue Apr 14 19:35:38 2015
@@ -602,6 +602,7 @@
extern NCodeTemplate* MC_(tmpl__LOADV64le_on_64);
extern NCodeTemplate* MC_(tmpl__LOADV32le_on_64);
+extern NCodeTemplate* MC_(tmpl__LOADV16le_on_64);
extern NCodeTemplate* MC_(tmpl__LOADV8_on_64);
Modified: branches/NCODE/memcheck/mc_main.c
==============================================================================
--- branches/NCODE/memcheck/mc_main.c (original)
+++ branches/NCODE/memcheck/mc_main.c Tue Apr 14 19:35:38 2015
@@ -4276,7 +4276,8 @@
VG_REGPARM(1) static ULong mc_LOADV64le_on_64_slow ( Addr a );
VG_REGPARM(1) static ULong mc_LOADV32le_on_64_slow ( Addr a );
-VG_REGPARM(1) static ULong mc_LOADV8_on_64_slow ( Addr a );
+VG_REGPARM(1) static ULong mc_LOADV16le_on_64_slow ( Addr a );
+VG_REGPARM(1) static ULong mc_LOADV8_on_64_slow ( Addr a );
static void* ncode_alloc ( UInt n ) {
return VG_(malloc)("mc.ncode_alloc (NCode, permanent)", n);
@@ -4295,6 +4296,7 @@
NCodeTemplate* MC_(tmpl__LOADV64le_on_64) = NULL;
NCodeTemplate* MC_(tmpl__LOADV32le_on_64) = NULL;
+NCodeTemplate* MC_(tmpl__LOADV16le_on_64) = NULL;
NCodeTemplate* MC_(tmpl__LOADV8_on_64) = NULL;
static NCodeTemplate* mk_tmpl__LOADV64le_on_64 ( NAlloc na )
@@ -4423,6 +4425,98 @@
return tmpl;
}
+static NCodeTemplate* mk_tmpl__LOADV16le_on_64 ( NAlloc na )
+{
+ NInstr** hot = na((11+1) * sizeof(NInstr*));
+ NInstr** cold = na((14+1) * sizeof(NInstr*));
+
+ NReg rINVALID = mkNRegINVALID();
+
+ NReg r0 = mkNReg(Nrr_Result, 0);
+ NReg a0 = mkNReg(Nrr_Argument, 0);
+ NReg s0 = mkNReg(Nrr_Scratch, 0);
+
+ /*
+ h0 tst.w a0, #0xFFFFFFF000000001 high-or-misaligned?
+ h1 bnz cold.12 yes, goto slow path
+ h2 shr.w s0, a0, #16 s0 = pri-map-ix
+ h3 ld.64 s0, [&pri_map[0] + s0 << #3] s0 = sec-map
+ h4 and.w r0, a0, #0xFFFF r0 = sec-map-offB
+ h5 shr.w r0, r0, #2 r0 = sec-map-ix
+ h6 ld.8 r0, [s0 + r0 << #0] r0 = sec-map-VABITS8
+ h7 cmp.w r0, #0xAA r0 == VABITS8_DEFINED?
+ h8 bnz cold.0 no, goto cold.0
+ h9 imm.w r0, #0xFFFFFFFFFFFF0000 VBITS8_DEFINED | top48safe
+ h10 nop continue
+
+ c0 cmp.w r0, #0x55 VABITS8_UNDEFINED
+ c1 bnz cold.4
+
+ c2 imm.w r0, #0xFFFFFFFFFFFFFFFF VBITS16_UNDEFINED | top48safe
+ c3 b hot.10
+
+ // r0 holds sec-map-VABITS8. a0 holds the address and is 2-aligned.
+ // Extract the relevant 4 bits of r0 and inspect.
+ c4 and.w s0, a0, #2 // addr & 2
+ c5 add.w s0, s0, s0 // 2 * (addr & 2)
+ c6 shr.w r0, r0, s0 // sec-map-VABITS8 >> (2 * (addr & 2))
+ c7 and.w r0, r0, #15 // (sec-map-VABITS8 >> (2 * (addr & 2))) & 15
+
+ c8 cmp.w r0, #A // VABITS4_DEFINED
+ c9 jz hot.9
+
+ c10 cmp.w r0, #5 // VABITS4_UNDEFINED
+ c11 jz cold.2
+
+ c12 call r0 = mc_LOADV16le_on_64_slow(a0)
+ c13 b hot.10
+ */
+ hot[0] = NInstr_SetFlagsWri (na, Nsf_TEST, a0, MASK(2));
+ hot[1] = NInstr_Branch (na, Ncc_NZ, mkNLabel(Nlz_Cold, 12));
+ hot[2] = NInstr_ShiftWri (na, Nsh_SHR, s0, a0, 16);
+ hot[3] = NInstr_LoadU (na, 8, s0, NEA_IRS(na, (HWord)&primary_map[0],
+ s0, 3));
+ hot[4] = NInstr_AluWri (na, Nalu_AND, r0, a0, 0xFFFF);
+ hot[5] = NInstr_ShiftWri (na, Nsh_SHR, r0, r0, 2);
+ hot[6] = NInstr_LoadU (na, 1, r0, NEA_RRS(na, s0, r0, 0));
+ hot[7] = NInstr_SetFlagsWri (na, Nsf_CMP, r0, VA_BITS8_DEFINED);
+ hot[8] = NInstr_Branch (na, Ncc_NZ, mkNLabel(Nlz_Cold, 0));
+ hot[9] = NInstr_ImmW (na, r0, 0xFFFFFFFFFFFF0000ULL
+ | (ULong)V_BITS16_DEFINED);
+ hot[10] = NInstr_Nop (na);
+
+ cold[0] = NInstr_SetFlagsWri (na, Nsf_CMP, r0, VA_BITS8_UNDEFINED);
+ cold[1] = NInstr_Branch (na, Ncc_NZ, mkNLabel(Nlz_Cold, 4));
+
+ cold[2] = NInstr_ImmW (na, r0, 0xFFFFFFFFFFFF0000ULL
+ | (ULong)V_BITS16_UNDEFINED);
+ cold[3] = NInstr_Branch (na, Ncc_ALWAYS, mkNLabel(Nlz_Hot, 10));
+
+ // r0 holds sec-map-VABITS8. a0 holds the address and is 2-aligned.
+ // Extract the relevant 4 bits of r0 and inspect.
+ cold[4] = NInstr_AluWri (na, Nalu_AND, s0, a0, 2);
+ cold[5] = NInstr_AluWrr (na, Nalu_ADD, s0, s0, s0);
+ cold[6] = NInstr_ShiftWrr (na, Nsh_SHR, r0, r0, s0);
+ cold[7] = NInstr_AluWri (na, Nalu_AND, r0, r0, 15);
+
+ cold[8] = NInstr_SetFlagsWri (na, Nsf_CMP, r0, 0xA);
+ cold[9] = NInstr_Branch (na, Ncc_Z, mkNLabel(Nlz_Hot, 9));
+
+ cold[10]= NInstr_SetFlagsWri (na, Nsf_CMP, r0, 0x5);
+ cold[11]= NInstr_Branch (na, Ncc_Z, mkNLabel(Nlz_Cold, 2));
+
+ cold[12]= NInstr_Call (na, rINVALID, r0, mkNRegVec1(na, a0),
+ (void*)& mc_LOADV16le_on_64_slow,
+ "mc_LOADV16le_on_64_slow");
+ cold[13]= NInstr_Branch (na, Ncc_ALWAYS, mkNLabel(Nlz_Hot, 10));
+
+ hot[11] = cold[14] = NULL;
+ NCodeTemplate* tmpl
+ = mkNCodeTemplate(na,"LOADV16le_on_64",
+ /*res, parms, scratch*/1, 1, 1, hot, cold);
+ return tmpl;
+}
+
static NCodeTemplate* mk_tmpl__LOADV8_on_64 ( NAlloc na )
{
NInstr** hot = na((11+1) * sizeof(NInstr*));
@@ -4520,9 +4614,11 @@
{
tl_assert(MC_(tmpl__LOADV64le_on_64) == NULL);
tl_assert(MC_(tmpl__LOADV32le_on_64) == NULL);
+ tl_assert(MC_(tmpl__LOADV16le_on_64) == NULL);
tl_assert(MC_(tmpl__LOADV8_on_64) == NULL);
MC_(tmpl__LOADV64le_on_64) = mk_tmpl__LOADV64le_on_64(ncode_alloc);
MC_(tmpl__LOADV32le_on_64) = mk_tmpl__LOADV32le_on_64(ncode_alloc);
+ MC_(tmpl__LOADV16le_on_64) = mk_tmpl__LOADV16le_on_64(ncode_alloc);
MC_(tmpl__LOADV8_on_64) = mk_tmpl__LOADV8_on_64(ncode_alloc);
}
@@ -4901,6 +4997,11 @@
{
return mc_LOADV16(a, False);
}
+VG_REGPARM(1) static ULong mc_LOADV16le_on_64_slow ( Addr a )
+{
+ return mc_LOADVn_slow( a, 16, False/*!isBigEndian*/ );
+}
+
/* True if the vabits4 in vabits8 indicate a and a+1 are accessible. */
static INLINE
Modified: branches/NCODE/memcheck/mc_translate.c
==============================================================================
--- branches/NCODE/memcheck/mc_translate.c (original)
+++ branches/NCODE/memcheck/mc_translate.c Tue Apr 14 19:35:38 2015
@@ -4626,42 +4626,62 @@
/* ------ BEGIN inline NCode ? ------ */
if (guardIsAlwaysTrue(guard) && mce->hWordTy == Ity_I64 && end == Iend_LE) {
- if (ty == Ity_I64) {
- /* Unconditional LOAD64le on 64 bit host. Generate inline code. */
- IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
- NCodeTemplate* tmpl = MC_(tmpl__LOADV64le_on_64);
- IRAtom** args = mkIRExprVec_1( addrAct );
- IRTemp* ress = mkIRTempVec_1( datavbits64 );
- stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
- return mkexpr(datavbits64);
- }
- if (ty == Ity_I32) {
- /* Unconditional LOAD32le on 64 bit host. Generate inline code. */
- IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
- NCodeTemplate* tmpl = MC_(tmpl__LOADV32le_on_64);
- IRAtom** args = mkIRExprVec_1( addrAct );
- IRTemp* ress = mkIRTempVec_1( datavbits64 );
- /* The NCode block produces a 64 bit value, but we need to
- truncate it to 32 bits. */
- stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
- IRAtom* datavbits32
- = assignNew('V', mce, Ity_I32, unop(Iop_64to32, mkexpr(datavbits64)));
- return datavbits32;
- }
- if (ty == Ity_I8) {
- /* Unconditional LOAD8 on 64 bit host. Generate inline code. */
- IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
- NCodeTemplate* tmpl = MC_(tmpl__LOADV8_on_64);
- IRAtom** args = mkIRExprVec_1( addrAct );
- IRTemp* ress = mkIRTempVec_1( datavbits64 );
- /* The NCode block produces a 64 bit value, but we need to
- truncate it to 8 bits. */
- stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
- IRAtom* datavbits8
- = assignNew('V', mce, Ity_I8, unop(Iop_64to8, mkexpr(datavbits64)));
- return datavbits8;
+ switch (ty) {
+ case Ity_I64: {
+ /* Unconditional LOAD64le on 64 bit host. Generate inline code. */
+ IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
+ NCodeTemplate* tmpl = MC_(tmpl__LOADV64le_on_64);
+ IRAtom** args = mkIRExprVec_1( addrAct );
+ IRTemp* ress = mkIRTempVec_1( datavbits64 );
+ stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
+ return mkexpr(datavbits64);
+ }
+ case Ity_I32: {
+ /* Unconditional LOAD32le on 64 bit host. Generate inline code. */
+ IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
+ NCodeTemplate* tmpl = MC_(tmpl__LOADV32le_on_64);
+ IRAtom** args = mkIRExprVec_1( addrAct );
+ IRTemp* ress = mkIRTempVec_1( datavbits64 );
+ /* The NCode block produces a 64 bit value, but we need to
+ truncate it to 32 bits. */
+ stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
+ IRAtom* datavbits32
+ = assignNew('V', mce, Ity_I32,
+ unop(Iop_64to32, mkexpr(datavbits64)));
+ return datavbits32;
+ }
+ case Ity_I16: {
+ /* Unconditional LOAD16le on 64 bit host. Generate inline code. */
+ IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
+ NCodeTemplate* tmpl = MC_(tmpl__LOADV16le_on_64);
+ IRAtom** args = mkIRExprVec_1( addrAct );
+ IRTemp* ress = mkIRTempVec_1( datavbits64 );
+ /* The NCode block produces a 64 bit value, but we need to
+ truncate it to 16 bits. */
+ stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
+ IRAtom* datavbits16
+ = assignNew('V', mce, Ity_I16,
+ unop(Iop_64to16, mkexpr(datavbits64)));
+ return datavbits16;
+ }
+ case Ity_I8: {
+ /* Unconditional LOAD8 on 64 bit host. Generate inline code. */
+ IRTemp datavbits64 = newTemp(mce, Ity_I64, VSh);
+ NCodeTemplate* tmpl = MC_(tmpl__LOADV8_on_64);
+ IRAtom** args = mkIRExprVec_1( addrAct );
+ IRTemp* ress = mkIRTempVec_1( datavbits64 );
+ /* The NCode block produces a 64 bit value, but we need to
+ truncate it to 8 bits. */
+ stmt( 'V', mce, IRStmt_NCode(tmpl, args, ress) );
+ IRAtom* datavbits8
+ = assignNew('V', mce, Ity_I8,
+ unop(Iop_64to8, mkexpr(datavbits64)));
+ return datavbits8;
+ }
+ default:
+ /* else fall through */
+ break;
}
- /* else fall through */
}
/* ------ END inline NCode ? ------ */
|