1/*
2 * gomacro - A Go interpreter with Lisp-like macros
3 *
4 * Copyright (C) 2018-2019 Massimiliano Ghilardi
5 *
6 *     This Source Code Form is subject to the terms of the Mozilla Public
7 *     License, v. 2.0. If a copy of the MPL was not distributed with this
8 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 *
11 * machine.go
12 *
13 *  Created on May 20, 2018
14 *      Author Massimiliano Ghilardi
15 */
16
17package amd64
18
19// ============================================================================
20// register
21const (
22	noregid = RegId(AMD64-1)<<8 + iota
23	RAX
24	RCX
25	RDX
26	RBX
27	RSP
28	RBP
29	RSI
30	RDI
31	R8
32	R9
33	R10
34	R11
35	R12
36	R13
37	R14
38	R15
39	RLo RegId = RAX
40	RHi RegId = R15
41	// suggested register to point to local variables
42	RVAR = RSI
43)
44
45var regName1 = [...]string{
46	RAX - RLo: "%al",
47	RCX - RLo: "%cl",
48	RDX - RLo: "%dl",
49	RBX - RLo: "%bl",
50	RSP - RLo: "%spl",
51	RBP - RLo: "%bpl",
52	RSI - RLo: "%sil",
53	RDI - RLo: "%dil",
54	R8 - RLo:  "%r8b",
55	R9 - RLo:  "%r9b",
56	R10 - RLo: "%r10b",
57	R11 - RLo: "%r11b",
58	R12 - RLo: "%r12b",
59	R13 - RLo: "%r13b",
60	R14 - RLo: "%r14b",
61	R15 - RLo: "%r15b",
62}
63var regName2 = [...]string{
64	RAX - RLo: "%ax",
65	RCX - RLo: "%cx",
66	RDX - RLo: "%dx",
67	RBX - RLo: "%bx",
68	RSP - RLo: "%sp",
69	RBP - RLo: "%bp",
70	RSI - RLo: "%si",
71	RDI - RLo: "%di",
72	R8 - RLo:  "%r8w",
73	R9 - RLo:  "%r9w",
74	R10 - RLo: "%r10w",
75	R11 - RLo: "%r11w",
76	R12 - RLo: "%r12w",
77	R13 - RLo: "%r13w",
78	R14 - RLo: "%r14w",
79	R15 - RLo: "%r15w",
80}
81var regName4 = [...]string{
82	RAX - RLo: "%eax",
83	RCX - RLo: "%ecx",
84	RDX - RLo: "%edx",
85	RBX - RLo: "%ebx",
86	RSP - RLo: "%esp",
87	RBP - RLo: "%ebp",
88	RSI - RLo: "%esi",
89	RDI - RLo: "%edi",
90	R8 - RLo:  "%r8d",
91	R9 - RLo:  "%r9d",
92	R10 - RLo: "%r10d",
93	R11 - RLo: "%r11d",
94	R12 - RLo: "%r12d",
95	R13 - RLo: "%r13d",
96	R14 - RLo: "%r14d",
97	R15 - RLo: "%r15d",
98}
99var regName8 = [...]string{
100	RAX - RLo: "%rax",
101	RCX - RLo: "%rcx",
102	RDX - RLo: "%rdx",
103	RBX - RLo: "%rbx",
104	RSP - RLo: "%rsp",
105	RBP - RLo: "%rbp",
106	RSI - RLo: "%rsi",
107	RDI - RLo: "%rdi",
108	R8 - RLo:  "%r8",
109	R9 - RLo:  "%r9",
110	R10 - RLo: "%r10",
111	R11 - RLo: "%r11",
112	R12 - RLo: "%r12",
113	R13 - RLo: "%r13",
114	R14 - RLo: "%r14",
115	R15 - RLo: "%r15",
116}
117
118func bits(id RegId) uint8 {
119	id.Validate()
120	return uint8(id - RLo)
121}
122
123func lohiId(id RegId) (uint8, uint8) {
124	bits := bits(id)
125	return bits & 0x7, (bits & 0x8) >> 3
126}
127
128func lohi(r Reg) (uint8, uint8) {
129	return lohiId(r.RegId())
130}
131
132// return number of assembler bytes needed to encode m.off
133func offlen(m Mem, id RegId) (offlen uint8, offbit uint8) {
134	moffset := m.Offset()
135	switch {
136	// (%rbp) and (%r13) registers must use 1-byte offset even if m.off == 0
137	case moffset == 0 && id != RBP && id != R13:
138		return 0, 0
139	case moffset == int32(int8(moffset)):
140		return 1, 0x40
141	default:
142		return 4, 0x80
143	}
144}
145
146func quirk24(asm *Asm, id RegId) *Asm {
147	if id == RSP || id == R12 {
148		asm.Bytes(0x24) // amd64 quirk
149	}
150	return asm
151}
152