-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathjitasm.Frontend.x86_32.h
123 lines (101 loc) · 4.03 KB
/
jitasm.Frontend.x86_32.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#pragma once
#ifndef jitasm_Frontend_x86_32_h__
#define jitasm_Frontend_x86_32_h__
#include "jitasm.x86.h"
#include "jitasm.x86_32.h"
#include "jitasm.Frontend.x86.h"
namespace jitasm
{
namespace x86_32
{
using namespace jitasm::x86;
namespace detail
{
using namespace jitasm::detail;
/**
* <b>Stack layout</b>
* \verbatim
* +-----------------------+
* | Caller return address |
* +=======================+========
* | ebp (rbp) |
* +-----------------------+ <-- ebp (rbp)
* | Saved gp registers |
* +-----------------------+
* | Padding for alignment |
* +-----------------------+ <-- Stack base
* | Spill slots and |
* | local variable |
* +-----------------------+ <-- esp (rsp)
* \endverbatim
*/
class StackManager
{
private:
Addr stack_base_;
uint32 stack_size_;
public:
StackManager() : stack_base_(RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), 0), stack_size_(0) {}
/// Get allocated stack size
uint32 GetSize() const { return (stack_size_ + 15) / 16 * 16; /* 16 bytes aligned*/ }
/// Get stack base
Addr GetStackBase() const { return stack_base_; }
/// Set stack base
void SetStackBase(const Addr& stack_base) { stack_base_ = stack_base; }
/// Allocate stack
Addr Alloc(uint32 size, uint32 alignment)
{
stack_size_ = (stack_size_ + alignment - 1) / alignment * alignment;
stack_size_ += size;
return stack_base_ - stack_size_;
}
};
}
template < typename Derived > struct Frontend$CRTP : jitasm::x86::Frontend$CRTP< Derived > /* using Curiously Recurring Template Pattern */
{
typedef jitasm::x86::Addr32 Addr;
typedef jitasm::x86::Reg32 Reg;
AddressingPtr<Opd8> byte_ptr;
AddressingPtr<Opd16> word_ptr;
AddressingPtr<Opd32> dword_ptr;
AddressingPtr<Opd64> qword_ptr;
AddressingPtr<Opd64> mmword_ptr;
AddressingPtr<Opd128> xmmword_ptr;
AddressingPtr<Opd256> ymmword_ptr;
AddressingPtr<Opd32> real4_ptr;
AddressingPtr<Opd64> real8_ptr;
AddressingPtr<Opd80> real10_ptr;
AddressingPtr<Opd16> m2byte_ptr;
AddressingPtr<Opd224> m28byte_ptr;
AddressingPtr<Opd864> m108byte_ptr;
AddressingPtr<Opd4096> m512byte_ptr;
Reg zax, zcx, zdx, zbx, zsp, zbp, zsi, zdi;
AddressingPtr<Opd32> ptr;
detail::StackManager stack_manager_;
Frontend$CRTP()
: jitasm::x86::Frontend$CRTP< Derived >(false),
zax(EAX),
zcx(ECX),
zdx(EDX),
zbx(EBX),
zsp(ESP),
zbp(EBP),
zsi(ESI),
zdi(EDI)
{
}
virtual ~Frontend$CRTP()
{
}
/////////////
void aaa(Reg16 const & a1 = ax) { AppendInstr(I_AAA, a1); }
void aad(Reg16 const & a1 = ax, Imm8 const & a2 = Imm8(5)) { AppendInstr(I_AAD, a1, a2); }
void aam(Reg16 const & a1 = ax, Imm8 const & a2 = Imm8(5)) { AppendInstr(I_AAM, a1, a2); }
void aas(Reg16 const & a1 = ax) { AppendInstr(I_AAS, a1); }
void arpl(Mem16 const & a1, Reg16 const & a2) { AppendInstr(I_ARPL, a1, a2); }
void bound(Reg16 const & a1, Mem32 const & a2) { AppendInstr(I_BOUND, a1, a2); }
void bound(Reg32 const & a1, Mem64 const & a2) { AppendInstr(I_BOUND, a1, a2); }
};
}
}
#endif // jitasm_Frontend_x86_32_h__