OLD | NEW |
(Empty) | |
| 1 // Copyright 2006-2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are |
| 4 // met: |
| 5 // |
| 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. |
| 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 |
| 28 #include "v8.h" |
| 29 |
| 30 #include "disassembler.h" |
| 31 #include "factory.h" |
| 32 #include "mips/simulator-mips.h" |
| 33 #include "mips/assembler-mips-inl.h" |
| 34 // For macro-assembler support |
| 35 #include "bootstrapper.h" |
| 36 #include "codegen-inl.h" |
| 37 #include "debug.h" |
| 38 #include "runtime.h" |
| 39 |
| 40 #include "cctest.h" |
| 41 |
| 42 using namespace v8::internal; |
| 43 |
| 44 |
| 45 // Define these function prototypes to match JSEntryFunction in execution.cc. |
| 46 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
| 47 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
| 48 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
| 49 |
| 50 |
| 51 static v8::Persistent<v8::Context> env; |
| 52 |
| 53 |
| 54 // The test framework does not accept flags on the command line, so we set them |
| 55 static void InitializeVM() { |
| 56 // disable compilation of natives by specifying an empty natives file |
| 57 FLAG_natives_file = ""; |
| 58 |
| 59 // enable generation of comments |
| 60 FLAG_debug_code = true; |
| 61 |
| 62 if (env.IsEmpty()) { |
| 63 env = v8::Context::New(); |
| 64 } |
| 65 } |
| 66 |
| 67 |
| 68 #define __ assm. |
| 69 |
| 70 TEST(MIPS0) { |
| 71 InitializeVM(); |
| 72 v8::HandleScope scope; |
| 73 |
| 74 MacroAssembler assm(NULL, 0); |
| 75 |
| 76 // addition |
| 77 __ addu(v0, a0, a1); |
| 78 __ jr(ra); |
| 79 __ nop(); |
| 80 |
| 81 CodeDesc desc; |
| 82 assm.GetCode(&desc); |
| 83 Object* code = Heap::CreateCode(desc, |
| 84 NULL, |
| 85 Code::ComputeFlags(Code::STUB), |
| 86 Handle<Object>(Heap::undefined_value())); |
| 87 CHECK(code->IsCode()); |
| 88 #ifdef DEBUG |
| 89 Code::cast(code)->Print(); |
| 90 #endif |
| 91 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); |
| 92 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); |
| 93 ::printf("f() = %d\n", res); |
| 94 CHECK_EQ(0xabc, res); |
| 95 } |
| 96 |
| 97 |
| 98 TEST(MIPS1) { |
| 99 InitializeVM(); |
| 100 v8::HandleScope scope; |
| 101 |
| 102 MacroAssembler assm(NULL, 0); |
| 103 Label L, C; |
| 104 |
| 105 __ mov(a1, a0); |
| 106 __ li(v0, 0); |
| 107 __ b(&C); |
| 108 __ nop(); |
| 109 |
| 110 __ bind(&L); |
| 111 __ add(v0, v0, a1); |
| 112 __ addiu(a1, a1, -1); |
| 113 |
| 114 __ bind(&C); |
| 115 __ xori(v1, a1, 0); |
| 116 __ Branch(ne, &L, v1, Operand(0)); |
| 117 __ nop(); |
| 118 |
| 119 __ jr(ra); |
| 120 __ nop(); |
| 121 |
| 122 CodeDesc desc; |
| 123 assm.GetCode(&desc); |
| 124 Object* code = Heap::CreateCode(desc, |
| 125 NULL, |
| 126 Code::ComputeFlags(Code::STUB), |
| 127 Handle<Object>(Heap::undefined_value())); |
| 128 CHECK(code->IsCode()); |
| 129 #ifdef DEBUG |
| 130 Code::cast(code)->Print(); |
| 131 #endif |
| 132 F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); |
| 133 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); |
| 134 ::printf("f() = %d\n", res); |
| 135 CHECK_EQ(1275, res); |
| 136 } |
| 137 |
| 138 |
| 139 TEST(MIPS2) { |
| 140 InitializeVM(); |
| 141 v8::HandleScope scope; |
| 142 |
| 143 MacroAssembler assm(NULL, 0); |
| 144 |
| 145 Label exit, error; |
| 146 |
| 147 // ----- Test all instructions. |
| 148 |
| 149 // Test lui, ori, and addiu, used in the li pseudo-instruction. |
| 150 // This way we can then safely load registers with chosen values. |
| 151 |
| 152 __ ori(t0, zero_reg, 0); |
| 153 __ lui(t0, 0x1234); |
| 154 __ ori(t0, t0, 0); |
| 155 __ ori(t0, t0, 0x0f0f); |
| 156 __ ori(t0, t0, 0xf0f0); |
| 157 __ addiu(t1, t0, 1); |
| 158 __ addiu(t2, t1, -0x10); |
| 159 |
| 160 // Load values in temporary registers |
| 161 __ li(t0, 0x00000004); |
| 162 __ li(t1, 0x00001234); |
| 163 __ li(t2, 0x12345678); |
| 164 __ li(t3, 0x7fffffff); |
| 165 __ li(t4, 0xfffffffc); |
| 166 __ li(t5, 0xffffedcc); |
| 167 __ li(t6, 0xedcba988); |
| 168 __ li(t7, 0x80000000); |
| 169 |
| 170 ///// SPECIAL class |
| 171 __ srl(v0, t2, 8); // 0x00123456 |
| 172 __ sll(v0, v0, 11); // 0x91a2b000 |
| 173 __ sra(v0, v0, 3); // 0xf2345600 |
| 174 __ srav(v0, v0, t0); // 0xff234560 |
| 175 __ sllv(v0, v0, t0); // 0xf2345600 |
| 176 __ srlv(v0, v0, t0); // 0x0f234560 |
| 177 __ Branch(ne, &error, v0, Operand(0x0f234560)); |
| 178 __ nop(); |
| 179 |
| 180 __ add(v0, t0, t1); // 0x00001238 |
| 181 __ sub(v0, v0, t0); // 0x00001234 |
| 182 __ Branch(ne, &error, v0, Operand(0x00001234)); |
| 183 __ nop(); |
| 184 __ addu(v1, t3, t0); |
| 185 __ Branch(ne, &error, v1, Operand(0x80000003)); |
| 186 __ nop(); |
| 187 __ subu(v1, t7, t0); // 0x7ffffffc |
| 188 __ Branch(ne, &error, v1, Operand(0x7ffffffc)); |
| 189 __ nop(); |
| 190 |
| 191 __ and_(v0, t1, t2); // 0x00001230 |
| 192 __ or_(v0, v0, t1); // 0x00001234 |
| 193 __ xor_(v0, v0, t2); // 0x1234444c |
| 194 __ nor(v0, v0, t2); // 0xedcba987 |
| 195 __ Branch(ne, &error, v0, Operand(0xedcba983)); |
| 196 __ nop(); |
| 197 |
| 198 __ slt(v0, t7, t3); |
| 199 __ Branch(ne, &error, v0, Operand(0x1)); |
| 200 __ nop(); |
| 201 __ sltu(v0, t7, t3); |
| 202 __ Branch(ne, &error, v0, Operand(0x0)); |
| 203 __ nop(); |
| 204 ///// end of SPECIAL class |
| 205 |
| 206 __ addi(v0, zero_reg, 0x7421); // 0x00007421 |
| 207 __ addi(v0, v0, -0x1); // 0x00007420 |
| 208 __ addiu(v0, v0, -0x20); // 0x00007400 |
| 209 __ Branch(ne, &error, v0, Operand(0x00007400)); |
| 210 __ nop(); |
| 211 __ addiu(v1, t3, 0x1); // 0x80000000 |
| 212 __ Branch(ne, &error, v1, Operand(0x80000000)); |
| 213 __ nop(); |
| 214 |
| 215 __ slti(v0, t1, 0x00002000); // 0x1 |
| 216 __ slti(v0, v0, 0xffff8000); // 0x0 |
| 217 __ Branch(ne, &error, v0, Operand(0x0)); |
| 218 __ nop(); |
| 219 __ sltiu(v0, t1, 0x00002000); // 0x1 |
| 220 __ sltiu(v0, v0, 0x00008000); // 0x1 |
| 221 __ Branch(ne, &error, v0, Operand(0x1)); |
| 222 __ nop(); |
| 223 |
| 224 __ andi(v0, t1, 0xf0f0); // 0x00001030 |
| 225 __ ori(v0, v0, 0x8a00); // 0x00009a30 |
| 226 __ xori(v0, v0, 0x83cc); // 0x000019fc |
| 227 __ Branch(ne, &error, v0, Operand(0x000019fc)); |
| 228 __ nop(); |
| 229 __ lui(v1, 0x8123); // 0x81230000 |
| 230 __ Branch(ne, &error, v1, Operand(0x81230000)); |
| 231 __ nop(); |
| 232 |
| 233 |
| 234 |
| 235 // Everything was correctly executed. Load the expected result. |
| 236 __ li(v0, 0x31415926); |
| 237 __ b(&exit); |
| 238 __ nop(); |
| 239 |
| 240 __ bind(&error); |
| 241 // Got an error. Return a wrong result. |
| 242 |
| 243 __ bind(&exit); |
| 244 __ jr(ra); |
| 245 __ nop(); |
| 246 |
| 247 |
| 248 CodeDesc desc; |
| 249 assm.GetCode(&desc); |
| 250 Object* code = Heap::CreateCode(desc, |
| 251 NULL, |
| 252 Code::ComputeFlags(Code::STUB), |
| 253 Handle<Object>(Heap::undefined_value())); |
| 254 CHECK(code->IsCode()); |
| 255 #ifdef DEBUG |
| 256 Code::cast(code)->Print(); |
| 257 #endif |
| 258 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); |
| 259 int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); |
| 260 ::printf("f() = %d\n", res); |
| 261 CHECK_EQ(0x31415926, res); |
| 262 } |
| 263 |
| 264 #undef __ |
| 265 |
OLD | NEW |