about summary refs log tree commit diff stats
path: root/src/dynarec/arm64/arm64_mapping.h
blob: 3e59f02d9bddec26cfea176861bac73b595f917c (plain) (blame)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef __ARM64_MAPPING_H__
#define __ARM64_MAPPING_H__


/* 
    ARM64 Linux Call Convention

SP          The Stack Pointer.
r30 LR      The Link Register.
r29 FP      The Frame Pointer
r19…r28     Callee-saved registers
r18         The Platform Register, if needed; otherwise a temporary register. See notes.
r17 IP1     The second intra-procedure-call temporary register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
r16 IP0     The first intra-procedure-call scratch register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
r9…r15      Temporary registers
r8          Indirect result location register
r0…r7       Parameter/result registers

For SIMD:
The first eight registers, v0-v7, are used to pass argument values into a subroutine and to return result values from a function. 
    They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).

Registers v8-v15 must be preserved by a callee across subroutine calls; 
    the remaining registers (v0-v7, v16-v31) do not need to be preserved (or should be preserved by the caller).
    Additionally, only the bottom 64 bits of each value stored in v8-v15 need to be preserved [8];
    it is the responsibility of the caller to preserve larger values.

For SVE:
z0-z7 are used to pass scalable vector arguments to a subroutine, and to return scalable vector results from a function.
    If a subroutine takes at least one argument in scalable vector registers or scalable predicate registers,
    or returns results in such regisers, the subroutine must ensure that the entire contents of z8-z23 are preserved across the call.
    In other cases it need only preserve the low 64 bits of z8-z15, as described in SIMD and Floating-Point registers.
p0-p3 are used to pass scalable predicate arguments to a subroutine and to return scalable predicate results from a function.
    If a subroutine takes at least one argument in scalable vector registers or scalable predicate registers,
    or returns results in such registers, the subroutine must ensure that p4-p15 are preserved across the call.
    In other cases it need not preserve any scalable predicate register contents.

*/

// x86 Register mapping
#define xRAX    10
#define xRCX    11
#define xRDX    12
#define xRBX    13
#define xRSP    14
#define xRBP    15
#define xRSI    16
#define xRDI    17
#define xR8     18
#define xR9     19
#define xR10    20
#define xR11    21
#define xR12    22
#define xR13    23
#define xR14    24
#define xR15    25
#define xFlags  26
#define xRIP    27
#define xSavedSP 28

// convert a x86 register to native according to the register mapping
#define TO_NAT(A) (xRAX + (A))

// 32bits version
#define wEAX    xRAX
#define wECX    xRCX
#define wEDX    xRDX
#define wEBX    xRBX
#define wESP    xRSP
#define wEBP    xRBP
#define wESI    xRSI
#define wEDI    xRDI
#define wR8     xR8
#define wR9     xR9
#define wR10    xR10
#define wR11    xR11
#define wR12    xR12
#define wR13    xR13
#define wR14    xR14
#define wR15    xR15
#define wFlags  xFlags
// scratch registers
#define x1      1
#define x2      2
#define x3      3
#define x4      4
#define x5      5
#define x6      6
#define x87pc   7
// x87 can be a scratch, but check if it's used as x87 PC and restore if needed in that case
// 32bits version of scratch
#define w1      x1
#define w2      x2
#define w3      x3
#define w4      x4
#define w5      x5
#define w6      x6
#define w87pc   x87pc
// emu is r0
#define xEmu    0
// ARM64 LR
#define xLR     30
// ARM64 SP is r31 but is a special register
#define xSP     31      
// xZR regs is 31
#define xZR     31
#define wZR     xZR

// conditions
// Z == 1
#define cEQ 0b0000
// Z != 1
#define cNE 0b0001
// C == 1
#define cCS 0b0010
// C == 1
#define cHS cCS
// C != 1
#define cCC 0b0011
// C != 1
#define cLO cCC
// N == 1
#define cMI 0b0100
// N != 1
#define cPL 0b0101
// V == 1
#define cVS 0b0110
// V != 1
#define cVC 0b0111
// C == 1 && Z == 0
#define cHI 0b1000
// C !=1 || Z == 1
#define cLS 0b1001
// N == V
#define cGE 0b1010
// N != V
#define cLT 0b1011
// N == V && Z == 0
#define cGT 0b1100
// N != V || Z == 1
#define cLE 0b1101
// always
#define c__ 0b1110

//FCMP type of opcode produce:
// if any NAN: CV / v1 == v2: ZC / v1 < v2: N / v1 > v2: C

#endif //__ARM64_MAPPING_H__