blob: 4ff228387e7800fea35444b9f4c56643af642110 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Ian Rogersbdb03912011-09-14 00:55:44 -070016
17#include "context_x86.h"
18
Ian Rogers67375ac2011-09-14 00:55:44 -070019#include "object.h"
Elliott Hughes85d15452011-09-16 17:33:01 -070020
Ian Rogersbdb03912011-09-14 00:55:44 -070021namespace art {
22namespace x86 {
23
Ian Rogers67375ac2011-09-14 00:55:44 -070024X86Context::X86Context() {
Ian Rogersad42e132011-09-17 20:23:33 -070025#ifndef NDEBUG
Ian Rogers7caad772012-03-30 01:07:54 -070026 // Initialize registers with easy to spot debug values.
Elliott Hughesba8eee12012-01-24 20:25:24 -080027 for (int i = 0; i < 8; i++) {
Elliott Hughes9c750f92012-04-05 12:07:59 -070028 gprs_[i] = kBadGprBase + i;
Ian Rogers67375ac2011-09-14 00:55:44 -070029 }
Ian Rogersad42e132011-09-17 20:23:33 -070030 eip_ = 0xEBAD601F;
31#endif
Ian Rogers67375ac2011-09-14 00:55:44 -070032}
33
Ian Rogers0399dde2012-06-06 17:09:28 -070034void X86Context::FillCalleeSaves(const StackVisitor& fr) {
Mathieu Chartier66f19252012-09-18 08:57:04 -070035 AbstractMethod* method = fr.GetMethod();
Ian Rogers67375ac2011-09-14 00:55:44 -070036 uint32_t core_spills = method->GetCoreSpillMask();
37 size_t spill_count = __builtin_popcount(core_spills);
Ian Rogers0399dde2012-06-06 17:09:28 -070038 DCHECK_EQ(method->GetFpSpillMask(), 0u);
39 size_t frame_size = method->GetFrameSizeInBytes();
Ian Rogers67375ac2011-09-14 00:55:44 -070040 if (spill_count > 0) {
Ian Rogers7caad772012-03-30 01:07:54 -070041 // Lowest number spill is furthest away, walk registers and fill into context.
42 int j = 2; // Offset j to skip return address spill.
Elliott Hughes362f9bc2011-10-17 18:56:41 -070043 for (int i = 0; i < 8; i++) {
Ian Rogers67375ac2011-09-14 00:55:44 -070044 if (((core_spills >> i) & 1) != 0) {
Ian Rogers0399dde2012-06-06 17:09:28 -070045 gprs_[i] = fr.LoadCalleeSave(spill_count - j, frame_size);
Ian Rogers67375ac2011-09-14 00:55:44 -070046 j++;
47 }
48 }
49 }
50}
51
Elliott Hughes9c750f92012-04-05 12:07:59 -070052void X86Context::SmashCallerSaves() {
53 gprs_[EAX] = 0; // This needs to be 0 because we want a null/zero return value.
54 gprs_[ECX] = kBadGprBase + ECX;
55 gprs_[EDX] = kBadGprBase + EDX;
56 gprs_[EBX] = kBadGprBase + EBX;
57}
58
Ian Rogersbdb03912011-09-14 00:55:44 -070059void X86Context::DoLongJump() {
Elliott Hughes85d15452011-09-16 17:33:01 -070060#if defined(__i386__)
Ian Rogers7caad772012-03-30 01:07:54 -070061 // We push all the registers using memory-memory pushes, we then pop-all to get the registers
62 // set up, we then pop esp which will move us down the stack to the delivery address. At the frame
63 // where the exception will be delivered, we push EIP so that the return will take us to the
64 // correct delivery instruction.
65 gprs_[ESP] -= 4;
Elliott Hughesba8eee12012-01-24 20:25:24 -080066 *(reinterpret_cast<uintptr_t*>(gprs_[ESP])) = eip_;
Elliott Hughes7834cbd2012-05-14 18:25:16 -070067 __asm__ __volatile__(
Ian Rogers67375ac2011-09-14 00:55:44 -070068 "pushl %4\n\t"
69 "pushl %0\n\t"
70 "pushl %1\n\t"
71 "pushl %2\n\t"
72 "pushl %3\n\t"
73 "pushl %4\n\t"
74 "pushl %5\n\t"
75 "pushl %6\n\t"
76 "pushl %7\n\t"
77 "popal\n\t"
78 "popl %%esp\n\t"
79 "ret\n\t"
80 : //output
81 : "g"(gprs_[EAX]), "g"(gprs_[ECX]), "g"(gprs_[EDX]), "g"(gprs_[EBX]),
82 "g"(gprs_[ESP]), "g"(gprs_[EBP]), "g"(gprs_[ESI]), "g"(gprs_[EDI])
Ian Rogersbdb03912011-09-14 00:55:44 -070083 :); // clobber
Elliott Hughes85d15452011-09-16 17:33:01 -070084#else
Ian Rogers67375ac2011-09-14 00:55:44 -070085 UNIMPLEMENTED(FATAL);
Elliott Hughes85d15452011-09-16 17:33:01 -070086#endif
Ian Rogersbdb03912011-09-14 00:55:44 -070087}
88
89} // namespace x86
90} // namespace art