• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2010 the V8 project authors. All rights reserved.
34 
35 
36 #ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_
37 #define V8_MIPS_ASSEMBLER_MIPS_INL_H_
38 
39 #include "mips/assembler-mips.h"
40 #include "cpu.h"
41 
42 
43 namespace v8 {
44 namespace internal {
45 
46 // -----------------------------------------------------------------------------
47 // Condition
48 
NegateCondition(Condition cc)49 Condition NegateCondition(Condition cc) {
50   ASSERT(cc != cc_always);
51   return static_cast<Condition>(cc ^ 1);
52 }
53 
54 
55 // -----------------------------------------------------------------------------
56 // Operand and MemOperand
57 
Operand(int32_t immediate,RelocInfo::Mode rmode)58 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode)  {
59   rm_ = no_reg;
60   imm32_ = immediate;
61   rmode_ = rmode;
62 }
63 
Operand(const ExternalReference & f)64 Operand::Operand(const ExternalReference& f)  {
65   rm_ = no_reg;
66   imm32_ = reinterpret_cast<int32_t>(f.address());
67   rmode_ = RelocInfo::EXTERNAL_REFERENCE;
68 }
69 
Operand(const char * s)70 Operand::Operand(const char* s) {
71   rm_ = no_reg;
72   imm32_ = reinterpret_cast<int32_t>(s);
73   rmode_ = RelocInfo::EMBEDDED_STRING;
74 }
75 
Operand(Smi * value)76 Operand::Operand(Smi* value) {
77   rm_ = no_reg;
78   imm32_ =  reinterpret_cast<intptr_t>(value);
79   rmode_ = RelocInfo::NONE;
80 }
81 
Operand(Register rm)82 Operand::Operand(Register rm) {
83   rm_ = rm;
84 }
85 
is_reg()86 bool Operand::is_reg() const {
87   return rm_.is_valid();
88 }
89 
90 
91 
92 // -----------------------------------------------------------------------------
93 // RelocInfo
94 
apply(intptr_t delta)95 void RelocInfo::apply(intptr_t delta) {
96   // On MIPS we do not use pc relative addressing, so we don't need to patch the
97   // code here.
98 }
99 
100 
target_address()101 Address RelocInfo::target_address() {
102   ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
103   return Assembler::target_address_at(pc_);
104 }
105 
106 
target_address_address()107 Address RelocInfo::target_address_address() {
108   ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
109   return reinterpret_cast<Address>(pc_);
110 }
111 
112 
set_target_address(Address target)113 void RelocInfo::set_target_address(Address target) {
114   ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
115   Assembler::set_target_address_at(pc_, target);
116 }
117 
118 
target_object()119 Object* RelocInfo::target_object() {
120   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
121   return reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
122 }
123 
124 
target_object_handle(Assembler * origin)125 Handle<Object> RelocInfo::target_object_handle(Assembler *origin) {
126   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
127   return Handle<Object>(reinterpret_cast<Object**>(
128       Assembler::target_address_at(pc_)));
129 }
130 
131 
target_object_address()132 Object** RelocInfo::target_object_address() {
133   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
134   return reinterpret_cast<Object**>(pc_);
135 }
136 
137 
set_target_object(Object * target)138 void RelocInfo::set_target_object(Object* target) {
139   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
140   Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target));
141 }
142 
143 
target_reference_address()144 Address* RelocInfo::target_reference_address() {
145   ASSERT(rmode_ == EXTERNAL_REFERENCE);
146   return reinterpret_cast<Address*>(pc_);
147 }
148 
149 
call_address()150 Address RelocInfo::call_address() {
151   ASSERT(IsPatchedReturnSequence());
152   // The 2 instructions offset assumes patched return sequence.
153   ASSERT(IsJSReturn(rmode()));
154   return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize);
155 }
156 
157 
set_call_address(Address target)158 void RelocInfo::set_call_address(Address target) {
159   ASSERT(IsPatchedReturnSequence());
160   // The 2 instructions offset assumes patched return sequence.
161   ASSERT(IsJSReturn(rmode()));
162   Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target;
163 }
164 
165 
call_object()166 Object* RelocInfo::call_object() {
167   return *call_object_address();
168 }
169 
170 
call_object_address()171 Object** RelocInfo::call_object_address() {
172   ASSERT(IsPatchedReturnSequence());
173   // The 2 instructions offset assumes patched return sequence.
174   ASSERT(IsJSReturn(rmode()));
175   return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
176 }
177 
178 
set_call_object(Object * target)179 void RelocInfo::set_call_object(Object* target) {
180   *call_object_address() = target;
181 }
182 
183 
IsPatchedReturnSequence()184 bool RelocInfo::IsPatchedReturnSequence() {
185 #ifdef DEBUG
186   PrintF("%s - %d - %s : Checking for jal(r)",
187       __FILE__, __LINE__, __func__);
188 #endif
189   return ((Assembler::instr_at(pc_) & kOpcodeMask) == SPECIAL) &&
190          (((Assembler::instr_at(pc_) & kFunctionFieldMask) == JAL) ||
191           ((Assembler::instr_at(pc_) & kFunctionFieldMask) == JALR));
192 }
193 
194 
195 // -----------------------------------------------------------------------------
196 // Assembler
197 
198 
CheckBuffer()199 void Assembler::CheckBuffer() {
200   if (buffer_space() <= kGap) {
201     GrowBuffer();
202   }
203 }
204 
205 
emit(Instr x)206 void Assembler::emit(Instr x) {
207   CheckBuffer();
208   *reinterpret_cast<Instr*>(pc_) = x;
209   pc_ += kInstrSize;
210 }
211 
212 
213 } }  // namespace v8::internal
214 
215 #endif  // V8_MIPS_ASSEMBLER_MIPS_INL_H_
216