1 /*
2 * Copyright (C) 2023 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 // x86_64 machine IR insns debugging.
18
19 #include "berberis/backend/x86_64/code_debug.h"
20
21 #include <cinttypes>
22 #include <string>
23
24 #include "berberis/base/logging.h"
25 #include "berberis/base/stringprintf.h"
26
27 // TODO(b/179708579): share this code with 32-bit backend.
28
29 using std::string;
30
31 namespace berberis {
32
GetMachineHardRegDebugName(MachineReg r)33 const char* GetMachineHardRegDebugName(MachineReg r) {
34 static const char* kHardRegs[] = {
35 "?", "r8", "r9", "r10", "r11", "rsi", "rdi", "rax", "rbx",
36 "rcx", "rdx", "rbp", "rsp", "r12", "r13", "r14", "r15", "?",
37 "?", "eflags", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6",
38 "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
39 };
40 CHECK_LT(static_cast<unsigned>(r.reg()), std::size(kHardRegs));
41 return kHardRegs[r.reg()];
42 }
43
44 namespace x86_64 {
45
46 namespace {
47
ScaleToInt(MachineMemOperandScale scale)48 int ScaleToInt(MachineMemOperandScale scale) {
49 switch (scale) {
50 case MachineMemOperandScale::kOne:
51 return 1;
52 case MachineMemOperandScale::kTwo:
53 return 2;
54 case MachineMemOperandScale::kFour:
55 return 4;
56 case MachineMemOperandScale::kEight:
57 return 8;
58 }
59 }
60
61 } // namespace
62
GetImplicitRegOperandDebugString(const MachineInsnX86_64 * insn,int i)63 string GetImplicitRegOperandDebugString(const MachineInsnX86_64* insn, int i) {
64 return StringPrintf("(%s)", GetRegOperandDebugString(insn, i).c_str());
65 }
66
GetAbsoluteMemOperandDebugString(const MachineInsnX86_64 * insn)67 string GetAbsoluteMemOperandDebugString(const MachineInsnX86_64* insn) {
68 return StringPrintf("[0x%x]", insn->disp());
69 }
70
GetBaseDispMemOperandDebugString(const MachineInsnX86_64 * insn,int i)71 string GetBaseDispMemOperandDebugString(const MachineInsnX86_64* insn, int i) {
72 return StringPrintf("[%s + 0x%x]", GetRegOperandDebugString(insn, i).c_str(), insn->disp());
73 }
74
GetIndexDispMemOperandDebugString(const MachineInsnX86_64 * insn,int i)75 string GetIndexDispMemOperandDebugString(const MachineInsnX86_64* insn, int i) {
76 return StringPrintf("[%s * %d + 0x%x]",
77 GetRegOperandDebugString(insn, i).c_str(),
78 ScaleToInt(insn->scale()),
79 insn->disp());
80 }
81
GetBaseIndexDispMemOperandDebugString(const MachineInsnX86_64 * insn,int i)82 string GetBaseIndexDispMemOperandDebugString(const MachineInsnX86_64* insn, int i) {
83 return StringPrintf("[%s + %s * %d + 0x%x]",
84 GetRegOperandDebugString(insn, i).c_str(),
85 GetRegOperandDebugString(insn, i + 1).c_str(),
86 ScaleToInt(insn->scale()),
87 insn->disp());
88 }
89
GetImmOperandDebugString(const MachineInsnX86_64 * insn)90 string GetImmOperandDebugString(const MachineInsnX86_64* insn) {
91 return StringPrintf("0x%" PRIx64, insn->imm());
92 }
93
GetCondOperandDebugString(const MachineInsnX86_64 * insn)94 string GetCondOperandDebugString(const MachineInsnX86_64* insn) {
95 return GetCondName(insn->cond());
96 }
97
GetLabelOperandDebugString(const MachineInsnX86_64 * insn)98 string GetLabelOperandDebugString(const MachineInsnX86_64* insn) {
99 return GetImmOperandDebugString(insn);
100 }
101
GetDebugString() const102 string CallImm::GetDebugString() const {
103 string out(StringPrintf("CALL 0x%" PRIx64, imm()));
104 for (int i = 0; i < NumRegOperands(); ++i) {
105 out += ", ";
106 out += GetRegOperandDebugString(this, i);
107 }
108 return out;
109 }
110
GetDebugString() const111 string CallImmArg::GetDebugString() const {
112 return "CALL_ARG " + GetRegOperandDebugString(this, 0);
113 }
114
115 } // namespace x86_64
116
117 } // namespace berberis
118