• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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  */
16 
17 #ifndef BERBERIS_ASSEMBLER_COMMON_H_
18 #define BERBERIS_ASSEMBLER_COMMON_H_
19 
20 #include <stdint.h>
21 
22 #include <string>
23 #include <utility>
24 
25 #include "berberis/assembler/machine_code.h"
26 #include "berberis/base/arena_alloc.h"
27 #include "berberis/base/arena_vector.h"
28 #include "berberis/base/logging.h"
29 #include "berberis/base/macros.h"  // DISALLOW_IMPLICIT_CONSTRUCTORS
30 
31 namespace berberis {
32 
33 class AssemblerBase {
34  public:
AssemblerBase(MachineCode * code)35   explicit AssemblerBase(MachineCode* code) : jumps_(code->arena()), code_(code) {}
36 
~AssemblerBase()37   ~AssemblerBase() {}
38 
39   class Label {
40    public:
Label()41     Label() : position_(kInvalid) {}
42 
43     // Label position is offset from the start of MachineCode
44     // where it is bound to.
position()45     uint32_t position() const { return position_; }
46 
Bind(uint32_t position)47     void Bind(uint32_t position) {
48       CHECK(!IsBound());
49       position_ = position;
50     }
51 
IsBound()52     bool IsBound() const { return position_ != kInvalid; }
53 
54    protected:
55     static const uint32_t kInvalid = 0xffffffff;
56     uint32_t position_;
57 
58    private:
59     DISALLOW_COPY_AND_ASSIGN(Label);
60   };
61 
pc()62   uint32_t pc() const { return code_->code_offset(); }
63 
64   // Macro operations.
Emit8(uint8_t v)65   void Emit8(uint8_t v) { code_->AddU8(v); }
66 
Emit16(int16_t v)67   void Emit16(int16_t v) { code_->Add<int16_t>(v); }
68 
Emit32(int32_t v)69   void Emit32(int32_t v) { code_->Add<int32_t>(v); }
70 
Emit64(int64_t v)71   void Emit64(int64_t v) { code_->Add<int64_t>(v); }
72 
73   template <typename T>
EmitSequence(const T * v,uint32_t count)74   void EmitSequence(const T* v, uint32_t count) {
75     code_->AddSequence(v, sizeof(T) * count);
76   }
77 
Bind(Label * label)78   void Bind(Label* label) { label->Bind(pc()); }
79 
MakeLabel()80   Label* MakeLabel() { return NewInArena<Label>(code_->arena()); }
81 
SetRecoveryPoint(Label * recovery_label)82   void SetRecoveryPoint(Label* recovery_label) {
83     jumps_.push_back(Jump{recovery_label, pc(), true});
84   }
85 
86  protected:
87   template <typename T>
AddrAs(uint32_t offset)88   T* AddrAs(uint32_t offset) {
89     return code_->AddrAs<T>(offset);
90   }
91 
AddRelocation(uint32_t dst,RelocationType type,uint32_t pc,intptr_t data)92   void AddRelocation(uint32_t dst, RelocationType type, uint32_t pc, intptr_t data) {
93     code_->AddRelocation(dst, type, pc, data);
94   }
95 
96   // These are 'static' relocations, resolved when code is finalized.
97   // We also have 'dynamic' relocations, resolved when code is installed.
98   struct Jump {
99     const Label* label;
100     // Position of field to store offset.  Note: unless it's recovery label precomputed
101     // "distance from the end of instruction" is stored there.
102     //
103     // This is needed because we keep pointer to the rip-offset field while value stored
104     // there is counted from the end of instruction (on x86) or, sometimes, from the end
105     // of next instruction (ARM).
106     uint32_t pc;
107     bool is_recovery;
108   };
109   typedef ArenaVector<Jump> JumpList;
110   JumpList jumps_;
111 
112  private:
113   MachineCode* code_;
114 
115   DISALLOW_IMPLICIT_CONSTRUCTORS(AssemblerBase);
116 };
117 
118 }  // namespace berberis
119 
120 #endif  // BERBERIS_ASSEMBLER_COMMON_H_
121