test-assembler-arm.cc revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "disassembler.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/simulator-arm.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/assembler-arm-inl.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cctest.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Define these function prototypes to match JSEntryFunction in execution.cc. 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F2)(int x, int y, int p2, int p3, int p4); 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Persistent<v8::Context> env; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The test framework does not accept flags on the command line, so we set them 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeVM() { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // disable compilation of natives by specifying an empty natives file 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_natives_file = ""; 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // enable generation of comments 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_debug_code = true; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (env.IsEmpty()) { 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env = v8::Context::New(); 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(0) { 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r0, Operand(r1)); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Heap::CreateCode(desc, 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeFlags(Code::STUB), 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(Heap::undefined_value())); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(code->IsCode()); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::cast(code)->Print(); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0)); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, res); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(1) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r1, Operand(r0)); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0)); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(&C); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r0, Operand(r1)); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(r1, r1, Operand(1)); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ teq(r1, Operand(0)); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(ne, &L); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Heap::CreateCode(desc, 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeFlags(Code::STUB), 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(Heap::undefined_value())); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(code->IsCode()); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::cast(code)->Print(); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0)); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5050, res); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(2) { 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r1, Operand(r0)); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(1)); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(&C); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mul(r0, r1, r0); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(r1, r1, Operand(1)); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ teq(r1, Operand(0)); 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ b(ne, &L); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(pc, Operand(lr)); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // some relocated stuff here, not executed 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ RecordComment("dead code, just testing relocations"); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(Factory::true_value())); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ RecordComment("dead code, just testing immediate operands"); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(-1)); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xFF000000)); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xF0F0F0F0)); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r0, Operand(0xFFF0FFFF)); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Heap::CreateCode(desc, 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeFlags(Code::STUB), 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(Heap::undefined_value())); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(code->IsCode()); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::cast(code)->Print(); 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0)); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3628800, res); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(3) { 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef struct { 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int i; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char c; 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int16_t s; 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } T; 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block T t; 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler assm(NULL, 0); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(ip, Operand(sp)); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ sub(fp, ip, Operand(4)); 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r4, Operand(r0)); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i))); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r0, ASR, 1)); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ str(r2, MemOperand(r4, OFFSET_OF(T, i))); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c))); 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r2, Operand(r0)); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r2, LSL, 2)); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ strb(r2, MemOperand(r4, OFFSET_OF(T, c))); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s))); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(r0, r2, Operand(r0)); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(r2, Operand(r2, ASR, 3)); 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ strh(r2, MemOperand(r4, OFFSET_OF(T, s))); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Heap::CreateCode(desc, 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeFlags(Code::STUB), 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(Heap::undefined_value())); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(code->IsCode()); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::cast(code)->Print(); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.i = 100000; 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.c = 10; 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t.s = 1000; 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0)); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(101010, res); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(100000/2, t.i); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(10*4, t.c); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1000/8, t.s); 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __ 228