⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test-assembler-arm.cc

📁 Google浏览器V8内核代码
💻 CC
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "disassembler.h"#include "factory.h"#include "simulator-arm.h"#include "assembler-arm-inl.h"#include "cctest.h"using namespace v8::internal;// Define these function prototypes to match JSEntryFunction in execution.cc.typedef int (*F1)(int x, int p1, int p2, int p3, int p4);typedef int (*F2)(int x, int y, int p2, int p3, int p4);typedef int (*F3)(void* p, int p1, int p2, int p3, int p4);static v8::Persistent<v8::Context> env;// The test framework does not accept flags on the command line, so we set themstatic void InitializeVM() {  // disable compilation of natives by specifying an empty natives file  FLAG_natives_file = "";  // enable generation of comments  FLAG_debug_code = true;  if (env.IsEmpty()) {    env = v8::Context::New();  }}#define __ assm.TEST(0) {  InitializeVM();  v8::HandleScope scope;  Assembler assm(NULL, 0);  __ add(r0, r0, Operand(r1));  __ mov(pc, Operand(lr));  CodeDesc desc;  assm.GetCode(&desc);  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));  CHECK(code->IsCode());#ifdef DEBUG  Code::cast(code)->Print();#endif  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0));  ::printf("f() = %d\n", res);  CHECK_EQ(7, res);}TEST(1) {  InitializeVM();  v8::HandleScope scope;  Assembler assm(NULL, 0);  Label L, C;  __ mov(r1, Operand(r0));  __ mov(r0, Operand(0));  __ b(&C);  __ bind(&L);  __ add(r0, r0, Operand(r1));  __ sub(r1, r1, Operand(1));  __ bind(&C);  __ teq(r1, Operand(0));  __ b(ne, &L);  __ mov(pc, Operand(lr));  CodeDesc desc;  assm.GetCode(&desc);  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));  CHECK(code->IsCode());#ifdef DEBUG  Code::cast(code)->Print();#endif  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0));  ::printf("f() = %d\n", res);  CHECK_EQ(5050, res);}TEST(2) {  InitializeVM();  v8::HandleScope scope;  Assembler assm(NULL, 0);  Label L, C;  __ mov(r1, Operand(r0));  __ mov(r0, Operand(1));  __ b(&C);  __ bind(&L);  __ mul(r0, r1, r0);  __ sub(r1, r1, Operand(1));  __ bind(&C);  __ teq(r1, Operand(0));  __ b(ne, &L);  __ mov(pc, Operand(lr));  // some relocated stuff here, not executed  __ RecordComment("dead code, just testing relocations");  __ mov(r0, Operand(Factory::true_value()));  __ RecordComment("dead code, just testing immediate operands");  __ mov(r0, Operand(-1));  __ mov(r0, Operand(0xFF000000));  __ mov(r0, Operand(0xF0F0F0F0));  __ mov(r0, Operand(0xFFF0FFFF));  CodeDesc desc;  assm.GetCode(&desc);  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));  CHECK(code->IsCode());#ifdef DEBUG  Code::cast(code)->Print();#endif  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));  ::printf("f() = %d\n", res);  CHECK_EQ(3628800, res);}TEST(3) {  InitializeVM();  v8::HandleScope scope;  typedef struct {    int i;    char c;    int16_t s;  } T;  T t;  Assembler assm(NULL, 0);  Label L, C;  __ mov(ip, Operand(sp));  __ stm(db_w, sp, r4.bit() | fp.bit() | sp.bit() | lr.bit());  __ sub(fp, ip, Operand(4));  __ mov(r4, Operand(r0));  __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));  __ mov(r2, Operand(r0, ASR, 1));  __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));  __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));  __ add(r0, r2, Operand(r0));  __ mov(r2, Operand(r2, LSL, 2));  __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));  __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));  __ add(r0, r2, Operand(r0));  __ mov(r2, Operand(r2, ASR, 3));  __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));  __ ldm(ia, sp, r4.bit() | fp.bit() | sp.bit() | pc.bit());  CodeDesc desc;  assm.GetCode(&desc);  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));  CHECK(code->IsCode());#ifdef DEBUG  Code::cast(code)->Print();#endif  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());  t.i = 100000;  t.c = 10;  t.s = 1000;  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0));  ::printf("f() = %d\n", res);  CHECK_EQ(101010, res);  CHECK_EQ(100000/2, t.i);  CHECK_EQ(10*4, t.c);  CHECK_EQ(1000/8, t.s);}TEST(4) {  InitializeVM();  v8::HandleScope scope;  // enable jump elimination  bool je_save = FLAG_eliminate_jumps;  bool pje_save = FLAG_print_jump_elimination;  FLAG_eliminate_jumps = true;  FLAG_print_jump_elimination = true;  Assembler assm(NULL, 0);  Label L0, L1, L2, L3;  __ mov(r1, Operand(r0));  __ mov(r0, Operand(1));  __ b(&L0);  // can be eliminated  __ bind(&L0);  __ b(&L2);  __ bind(&L1);  __ mul(r0, r1, r0);  __ sub(r1, r1, Operand(1));  __ bind(&L2);  __ teq(r1, Operand(0));  __ b(ne, &L3);  // can be replaced by bne L1  __ mov(pc, Operand(lr));  __ bind(&L3);  __ b(&L1);  CodeDesc desc;  assm.GetCode(&desc);  // restore jump elimination flags  FLAG_eliminate_jumps = je_save;  FLAG_print_jump_elimination = pje_save;  Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB));  CHECK(code->IsCode());#ifdef DEBUG  Code::cast(code)->Print();#endif  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0));  ::printf("f() = %d\n", res);  CHECK_EQ(3628800, res);}#undef __

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -