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