| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 static const v8::internal::Register arg2 = rdx; | 79 static const v8::internal::Register arg2 = rdx; |
| 80 #else | 80 #else |
| 81 static const v8::internal::Register arg1 = rdi; | 81 static const v8::internal::Register arg1 = rdi; |
| 82 static const v8::internal::Register arg2 = rsi; | 82 static const v8::internal::Register arg2 = rsi; |
| 83 #endif | 83 #endif |
| 84 | 84 |
| 85 #define __ assm. | 85 #define __ assm. |
| 86 | 86 |
| 87 | 87 |
| 88 TEST(AssemblerX64ReturnOperation) { | 88 TEST(AssemblerX64ReturnOperation) { |
| 89 OS::Setup(); |
| 89 // Allocate an executable page of memory. | 90 // Allocate an executable page of memory. |
| 90 size_t actual_size; | 91 size_t actual_size; |
| 91 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 92 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 92 &actual_size, | 93 &actual_size, |
| 93 true)); | 94 true)); |
| 94 CHECK(buffer); | 95 CHECK(buffer); |
| 95 Assembler assm(buffer, static_cast<int>(actual_size)); | 96 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 96 | 97 |
| 97 // Assemble a simple function that copies argument 2 and returns it. | 98 // Assemble a simple function that copies argument 2 and returns it. |
| 98 __ movq(rax, arg2); | 99 __ movq(rax, arg2); |
| 99 __ nop(); | 100 __ nop(); |
| 100 __ ret(0); | 101 __ ret(0); |
| 101 | 102 |
| 102 CodeDesc desc; | 103 CodeDesc desc; |
| 103 assm.GetCode(&desc); | 104 assm.GetCode(&desc); |
| 104 // Call the function from C++. | 105 // Call the function from C++. |
| 105 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 106 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 106 CHECK_EQ(2, result); | 107 CHECK_EQ(2, result); |
| 107 } | 108 } |
| 108 | 109 |
| 109 TEST(AssemblerX64StackOperations) { | 110 TEST(AssemblerX64StackOperations) { |
| 111 OS::Setup(); |
| 110 // Allocate an executable page of memory. | 112 // Allocate an executable page of memory. |
| 111 size_t actual_size; | 113 size_t actual_size; |
| 112 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 114 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 113 &actual_size, | 115 &actual_size, |
| 114 true)); | 116 true)); |
| 115 CHECK(buffer); | 117 CHECK(buffer); |
| 116 Assembler assm(buffer, static_cast<int>(actual_size)); | 118 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 117 | 119 |
| 118 // Assemble a simple function that copies argument 2 and returns it. | 120 // Assemble a simple function that copies argument 2 and returns it. |
| 119 // We compile without stack frame pointers, so the gdb debugger shows | 121 // We compile without stack frame pointers, so the gdb debugger shows |
| (...skipping 11 matching lines...) Expand all Loading... |
| 131 __ ret(0); | 133 __ ret(0); |
| 132 | 134 |
| 133 CodeDesc desc; | 135 CodeDesc desc; |
| 134 assm.GetCode(&desc); | 136 assm.GetCode(&desc); |
| 135 // Call the function from C++. | 137 // Call the function from C++. |
| 136 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 138 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 137 CHECK_EQ(2, result); | 139 CHECK_EQ(2, result); |
| 138 } | 140 } |
| 139 | 141 |
| 140 TEST(AssemblerX64ArithmeticOperations) { | 142 TEST(AssemblerX64ArithmeticOperations) { |
| 143 OS::Setup(); |
| 141 // Allocate an executable page of memory. | 144 // Allocate an executable page of memory. |
| 142 size_t actual_size; | 145 size_t actual_size; |
| 143 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 146 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 144 &actual_size, | 147 &actual_size, |
| 145 true)); | 148 true)); |
| 146 CHECK(buffer); | 149 CHECK(buffer); |
| 147 Assembler assm(buffer, static_cast<int>(actual_size)); | 150 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 148 | 151 |
| 149 // Assemble a simple function that adds arguments returning the sum. | 152 // Assemble a simple function that adds arguments returning the sum. |
| 150 __ movq(rax, arg2); | 153 __ movq(rax, arg2); |
| 151 __ addq(rax, arg1); | 154 __ addq(rax, arg1); |
| 152 __ ret(0); | 155 __ ret(0); |
| 153 | 156 |
| 154 CodeDesc desc; | 157 CodeDesc desc; |
| 155 assm.GetCode(&desc); | 158 assm.GetCode(&desc); |
| 156 // Call the function from C++. | 159 // Call the function from C++. |
| 157 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 160 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 158 CHECK_EQ(5, result); | 161 CHECK_EQ(5, result); |
| 159 } | 162 } |
| 160 | 163 |
| 161 TEST(AssemblerX64ImulOperation) { | 164 TEST(AssemblerX64ImulOperation) { |
| 165 OS::Setup(); |
| 162 // Allocate an executable page of memory. | 166 // Allocate an executable page of memory. |
| 163 size_t actual_size; | 167 size_t actual_size; |
| 164 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 168 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 165 &actual_size, | 169 &actual_size, |
| 166 true)); | 170 true)); |
| 167 CHECK(buffer); | 171 CHECK(buffer); |
| 168 Assembler assm(buffer, static_cast<int>(actual_size)); | 172 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 169 | 173 |
| 170 // Assemble a simple function that multiplies arguments returning the high | 174 // Assemble a simple function that multiplies arguments returning the high |
| 171 // word. | 175 // word. |
| 172 __ movq(rax, arg2); | 176 __ movq(rax, arg2); |
| 173 __ imul(arg1); | 177 __ imul(arg1); |
| 174 __ movq(rax, rdx); | 178 __ movq(rax, rdx); |
| 175 __ ret(0); | 179 __ ret(0); |
| 176 | 180 |
| 177 CodeDesc desc; | 181 CodeDesc desc; |
| 178 assm.GetCode(&desc); | 182 assm.GetCode(&desc); |
| 179 // Call the function from C++. | 183 // Call the function from C++. |
| 180 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 184 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 181 CHECK_EQ(0, result); | 185 CHECK_EQ(0, result); |
| 182 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); | 186 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); |
| 183 CHECK_EQ(1, result); | 187 CHECK_EQ(1, result); |
| 184 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); | 188 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); |
| 185 CHECK_EQ(-1, result); | 189 CHECK_EQ(-1, result); |
| 186 } | 190 } |
| 187 | 191 |
| 188 TEST(AssemblerX64MemoryOperands) { | 192 TEST(AssemblerX64MemoryOperands) { |
| 193 OS::Setup(); |
| 189 // Allocate an executable page of memory. | 194 // Allocate an executable page of memory. |
| 190 size_t actual_size; | 195 size_t actual_size; |
| 191 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 196 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 192 &actual_size, | 197 &actual_size, |
| 193 true)); | 198 true)); |
| 194 CHECK(buffer); | 199 CHECK(buffer); |
| 195 Assembler assm(buffer, static_cast<int>(actual_size)); | 200 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 196 | 201 |
| 197 // Assemble a simple function that copies argument 2 and returns it. | 202 // Assemble a simple function that copies argument 2 and returns it. |
| 198 __ push(rbp); | 203 __ push(rbp); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 212 __ ret(0); | 217 __ ret(0); |
| 213 | 218 |
| 214 CodeDesc desc; | 219 CodeDesc desc; |
| 215 assm.GetCode(&desc); | 220 assm.GetCode(&desc); |
| 216 // Call the function from C++. | 221 // Call the function from C++. |
| 217 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 222 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 218 CHECK_EQ(3, result); | 223 CHECK_EQ(3, result); |
| 219 } | 224 } |
| 220 | 225 |
| 221 TEST(AssemblerX64ControlFlow) { | 226 TEST(AssemblerX64ControlFlow) { |
| 227 OS::Setup(); |
| 222 // Allocate an executable page of memory. | 228 // Allocate an executable page of memory. |
| 223 size_t actual_size; | 229 size_t actual_size; |
| 224 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 230 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 225 &actual_size, | 231 &actual_size, |
| 226 true)); | 232 true)); |
| 227 CHECK(buffer); | 233 CHECK(buffer); |
| 228 Assembler assm(buffer, static_cast<int>(actual_size)); | 234 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 229 | 235 |
| 230 // Assemble a simple function that copies argument 1 and returns it. | 236 // Assemble a simple function that copies argument 1 and returns it. |
| 231 __ push(rbp); | 237 __ push(rbp); |
| 232 | 238 |
| 233 __ movq(rbp, rsp); | 239 __ movq(rbp, rsp); |
| 234 __ movq(rax, arg1); | 240 __ movq(rax, arg1); |
| 235 Label target; | 241 Label target; |
| 236 __ jmp(&target); | 242 __ jmp(&target); |
| 237 __ movq(rax, arg2); | 243 __ movq(rax, arg2); |
| 238 __ bind(&target); | 244 __ bind(&target); |
| 239 __ pop(rbp); | 245 __ pop(rbp); |
| 240 __ ret(0); | 246 __ ret(0); |
| 241 | 247 |
| 242 CodeDesc desc; | 248 CodeDesc desc; |
| 243 assm.GetCode(&desc); | 249 assm.GetCode(&desc); |
| 244 // Call the function from C++. | 250 // Call the function from C++. |
| 245 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 251 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
| 246 CHECK_EQ(3, result); | 252 CHECK_EQ(3, result); |
| 247 } | 253 } |
| 248 | 254 |
| 249 TEST(AssemblerX64LoopImmediates) { | 255 TEST(AssemblerX64LoopImmediates) { |
| 256 OS::Setup(); |
| 250 // Allocate an executable page of memory. | 257 // Allocate an executable page of memory. |
| 251 size_t actual_size; | 258 size_t actual_size; |
| 252 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 259 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
| 253 &actual_size, | 260 &actual_size, |
| 254 true)); | 261 true)); |
| 255 CHECK(buffer); | 262 CHECK(buffer); |
| 256 Assembler assm(buffer, static_cast<int>(actual_size)); | 263 Assembler assm(buffer, static_cast<int>(actual_size)); |
| 257 // Assemble two loops using rax as counter, and verify the ending counts. | 264 // Assemble two loops using rax as counter, and verify the ending counts. |
| 258 Label Fail; | 265 Label Fail; |
| 259 __ movq(rax, Immediate(-3)); | 266 __ movq(rax, Immediate(-3)); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 339 |
| 333 CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rsp)); | 340 CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rsp)); |
| 334 CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rbp)); | 341 CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rbp)); |
| 335 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rax)); | 342 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rax)); |
| 336 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r15)); | 343 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r15)); |
| 337 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r13)); | 344 CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r13)); |
| 338 } | 345 } |
| 339 } | 346 } |
| 340 | 347 |
| 341 #undef __ | 348 #undef __ |
| OLD | NEW |