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 ART_COMPILER_UTILS_X86_64_CONSTANTS_X86_64_H_
18 #define ART_COMPILER_UTILS_X86_64_CONSTANTS_X86_64_H_
19 
20 #include <iosfwd>
21 
22 #include "arch/x86_64/registers_x86_64.h"
23 #include "base/logging.h"
24 #include "base/macros.h"
25 #include "globals.h"
26 
27 namespace art {
28 namespace x86_64 {
29 
30 class CpuRegister {
31  public:
CpuRegister(Register r)32   explicit CpuRegister(Register r) : reg_(r) {}
CpuRegister(int r)33   explicit CpuRegister(int r) : reg_(Register(r)) {}
AsRegister()34   Register AsRegister() const {
35     return reg_;
36   }
LowBits()37   uint8_t LowBits() const {
38     return reg_ & 7;
39   }
NeedsRex()40   bool NeedsRex() const {
41     return reg_ > 7;
42   }
43  private:
44   const Register reg_;
45 };
46 std::ostream& operator<<(std::ostream& os, const CpuRegister& reg);
47 
48 class XmmRegister {
49  public:
XmmRegister(FloatRegister r)50   explicit XmmRegister(FloatRegister r) : reg_(r) {}
AsFloatRegister()51   FloatRegister AsFloatRegister() const {
52     return reg_;
53   }
LowBits()54   uint8_t LowBits() const {
55     return reg_ & 7;
56   }
NeedsRex()57   bool NeedsRex() const {
58     return reg_ > 7;
59   }
60  private:
61   const FloatRegister reg_;
62 };
63 std::ostream& operator<<(std::ostream& os, const XmmRegister& reg);
64 
65 enum X87Register {
66   ST0 = 0,
67   ST1 = 1,
68   ST2 = 2,
69   ST3 = 3,
70   ST4 = 4,
71   ST5 = 5,
72   ST6 = 6,
73   ST7 = 7,
74   kNumberOfX87Registers = 8,
75   kNoX87Register = -1  // Signals an illegal register.
76 };
77 std::ostream& operator<<(std::ostream& os, const X87Register& reg);
78 
79 enum ScaleFactor {
80   TIMES_1 = 0,
81   TIMES_2 = 1,
82   TIMES_4 = 2,
83   TIMES_8 = 3
84 };
85 
86 enum Condition {
87   kOverflow     =  0,
88   kNoOverflow   =  1,
89   kBelow        =  2,
90   kAboveEqual   =  3,
91   kEqual        =  4,
92   kNotEqual     =  5,
93   kBelowEqual   =  6,
94   kAbove        =  7,
95   kSign         =  8,
96   kNotSign      =  9,
97   kParityEven   = 10,
98   kParityOdd    = 11,
99   kLess         = 12,
100   kGreaterEqual = 13,
101   kLessEqual    = 14,
102   kGreater      = 15,
103 
104   kZero         = kEqual,
105   kNotZero      = kNotEqual,
106   kNegative     = kSign,
107   kPositive     = kNotSign
108 };
109 
110 
111 class Instr {
112  public:
113   static const uint8_t kHltInstruction = 0xF4;
114   // We prefer not to use the int3 instruction since it conflicts with gdb.
115   static const uint8_t kBreakPointInstruction = kHltInstruction;
116 
IsBreakPoint()117   bool IsBreakPoint() {
118     return (*reinterpret_cast<const uint8_t*>(this)) == kBreakPointInstruction;
119   }
120 
121   // Instructions are read out of a code stream. The only way to get a
122   // reference to an instruction is to convert a pointer. There is no way
123   // to allocate or create instances of class Instr.
124   // Use the At(pc) function to create references to Instr.
At(uintptr_t pc)125   static Instr* At(uintptr_t pc) { return reinterpret_cast<Instr*>(pc); }
126 
127  private:
128   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
129 };
130 
131 }  // namespace x86_64
132 }  // namespace art
133 
134 #endif  // ART_COMPILER_UTILS_X86_64_CONSTANTS_X86_64_H_
135