1/*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2011-2013, Rene Gollent, rene@gollent.com.
5 * Distributed under the terms of the MIT License.
6 */
7#ifndef CPU_STATE_X86_64_H
8#define CPU_STATE_X86_64_H
9
10#include <bitset>
11
12#include <debugger.h>
13
14#include "CpuState.h"
15
16
17enum {
18	X86_64_REGISTER_RIP = 0,
19	X86_64_REGISTER_RSP,
20	X86_64_REGISTER_RBP,
21
22	X86_64_REGISTER_RAX,
23	X86_64_REGISTER_RBX,
24	X86_64_REGISTER_RCX,
25	X86_64_REGISTER_RDX,
26
27	X86_64_REGISTER_RSI,
28	X86_64_REGISTER_RDI,
29
30	X86_64_REGISTER_R8,
31	X86_64_REGISTER_R9,
32	X86_64_REGISTER_R10,
33	X86_64_REGISTER_R11,
34	X86_64_REGISTER_R12,
35	X86_64_REGISTER_R13,
36	X86_64_REGISTER_R14,
37	X86_64_REGISTER_R15,
38
39	X86_64_REGISTER_CS,
40	X86_64_REGISTER_DS,
41	X86_64_REGISTER_ES,
42	X86_64_REGISTER_FS,
43	X86_64_REGISTER_GS,
44	X86_64_REGISTER_SS,
45
46	X86_64_INT_REGISTER_END,
47
48	X86_64_REGISTER_ST0,
49	X86_64_REGISTER_ST1,
50	X86_64_REGISTER_ST2,
51	X86_64_REGISTER_ST3,
52	X86_64_REGISTER_ST4,
53	X86_64_REGISTER_ST5,
54	X86_64_REGISTER_ST6,
55	X86_64_REGISTER_ST7,
56
57	X86_64_FP_REGISTER_END,
58
59	X86_64_REGISTER_MM0,
60	X86_64_REGISTER_MM1,
61	X86_64_REGISTER_MM2,
62	X86_64_REGISTER_MM3,
63	X86_64_REGISTER_MM4,
64	X86_64_REGISTER_MM5,
65	X86_64_REGISTER_MM6,
66	X86_64_REGISTER_MM7,
67
68	X86_64_MMX_REGISTER_END,
69
70	X86_64_REGISTER_XMM0,
71	X86_64_REGISTER_XMM1,
72	X86_64_REGISTER_XMM2,
73	X86_64_REGISTER_XMM3,
74	X86_64_REGISTER_XMM4,
75	X86_64_REGISTER_XMM5,
76	X86_64_REGISTER_XMM6,
77	X86_64_REGISTER_XMM7,
78	X86_64_REGISTER_XMM8,
79	X86_64_REGISTER_XMM9,
80	X86_64_REGISTER_XMM10,
81	X86_64_REGISTER_XMM11,
82	X86_64_REGISTER_XMM12,
83	X86_64_REGISTER_XMM13,
84	X86_64_REGISTER_XMM14,
85	X86_64_REGISTER_XMM15,
86
87	X86_64_XMM_REGISTER_END,
88
89	X86_64_REGISTER_COUNT
90};
91
92
93#define X86_64_INT_REGISTER_COUNT X86_64_INT_REGISTER_END
94#define X86_64_FP_REGISTER_COUNT (X86_64_FP_REGISTER_END \
95	- X86_64_INT_REGISTER_END)
96#define X86_64_MMX_REGISTER_COUNT (X86_64_MMX_REGISTER_END \
97	- X86_64_FP_REGISTER_END)
98#define X86_64_XMM_REGISTER_COUNT (X86_64_XMM_REGISTER_END \
99	- X86_64_MMX_REGISTER_END)
100
101
102struct x86_64_ymm_register {
103	unsigned long value[4];
104};
105
106
107class CpuStateX8664 : public CpuState {
108public:
109								CpuStateX8664();
110								CpuStateX8664(const x86_64_debug_cpu_state& state);
111	virtual						~CpuStateX8664();
112
113	virtual	status_t			Clone(CpuState*& _clone) const;
114
115	virtual	status_t			UpdateDebugState(void* state, size_t size)
116									const;
117
118	virtual	target_addr_t		InstructionPointer() const;
119	virtual void				SetInstructionPointer(target_addr_t address);
120
121	virtual	target_addr_t		StackFramePointer() const;
122	virtual	target_addr_t		StackPointer() const;
123	virtual	bool				GetRegisterValue(const Register* reg,
124									BVariant& _value) const;
125	virtual	bool				SetRegisterValue(const Register* reg,
126									const BVariant& value);
127
128			uint64				InterruptVector() const
129									{ return fInterruptVector; }
130
131			bool				IsRegisterSet(int32 index) const;
132
133			uint64				IntRegisterValue(int32 index) const;
134			void				SetIntRegister(int32 index, uint64 value);
135
136private:
137			double				FloatRegisterValue(int32 index) const;
138			void				SetFloatRegister(int32 index, double value);
139
140			const void*			MMXRegisterValue(int32 index) const;
141			void				SetMMXRegister(int32 index,
142									const uint8* value);
143
144			const void*			XMMRegisterValue(int32 index) const;
145			void				SetXMMRegister(int32 index,
146									const uint8* highValue, const uint8* lowValue);
147
148			void				UnsetRegister(int32 index);
149
150private:
151	typedef std::bitset<X86_64_REGISTER_COUNT> RegisterBitSet;
152
153private:
154			uint64				fIntRegisters[X86_64_INT_REGISTER_COUNT];
155			double				fFloatRegisters[X86_64_FP_REGISTER_COUNT];
156			x86_64_fp_register	fMMXRegisters[X86_64_MMX_REGISTER_COUNT];
157			x86_64_ymm_register	fXMMRegisters[X86_64_XMM_REGISTER_COUNT];
158			RegisterBitSet		fSetRegisters;
159			uint64				fInterruptVector;
160};
161
162
163#endif	// CPU_STATE_X86_64_H
164