1 |
dpavlin |
1 |
/* |
2 |
|
|
* Cisco 7200 Simulator. |
3 |
|
|
* X86 Assembly-optimized routines. |
4 |
|
|
* |
5 |
|
|
* Copyright (c) 2006 Christophe Fillot (cf@utc.fr) |
6 |
|
|
*/ |
7 |
|
|
|
8 |
|
|
#define DYNAMIPS_ASM |
9 |
|
|
|
10 |
|
|
#include "asmdefs.h" |
11 |
|
|
#include "memory.h" |
12 |
|
|
|
13 |
|
|
#if defined(CYGWIN) || defined(__APPLE__) |
14 |
|
|
#define _P(f) _##f |
15 |
|
|
#else |
16 |
|
|
#define _P(f) f |
17 |
|
|
#endif |
18 |
|
|
|
19 |
|
|
/* |
20 |
|
|
* Increment the count register. When value in compare register is hit, |
21 |
|
|
* trigger the timer interrupt. |
22 |
|
|
*/ |
23 |
|
|
.globl _P(mips64_inc_cp0_cnt_asm) |
24 |
|
|
_P(mips64_inc_cp0_cnt_asm): |
25 |
|
|
movl CP0_VCNT_OFS(%edi), %ecx |
26 |
|
|
incl %ecx |
27 |
|
|
movl %ecx, CP0_VCNT_OFS(%edi) |
28 |
|
|
cmpl %ecx, CP0_VCMP_OFS(%edi) |
29 |
|
|
jne 1f |
30 |
|
|
movl %edi, %eax |
31 |
|
|
call _P(mips64_trigger_timer_irq) |
32 |
|
|
1: |
33 |
|
|
ret |
34 |
|
|
|
35 |
|
|
/* |
36 |
|
|
* MTS32 Load Word (LW) fast version. |
37 |
|
|
* |
38 |
|
|
* Inputs: |
39 |
|
|
* %edi : cpu instance |
40 |
|
|
* %ebx : target register |
41 |
|
|
* %edx : virtual address (%ecx is high 32-bit word) |
42 |
|
|
*/ |
43 |
|
|
.globl _P(mts32_lw_asm) |
44 |
|
|
_P(mts32_lw_asm): |
45 |
|
|
pushl %esi |
46 |
|
|
movl $((1 << (MTS32_LEVEL2_BITS + MTS32_OFFSET_BITS)) - 1), %ecx |
47 |
|
|
|
48 |
|
|
/* compute L1 pos */ |
49 |
|
|
movl %edx, %eax |
50 |
|
|
shr $(MTS32_LEVEL2_BITS + MTS32_OFFSET_BITS), %eax |
51 |
|
|
movl MTS_L1_OFS(%edi), %esi |
52 |
|
|
movl (%esi,%eax,4), %esi |
53 |
|
|
|
54 |
|
|
/* %esi = L1 entry */ |
55 |
|
|
movl %esi, %eax |
56 |
|
|
andl $MTS_ACC_MASK, %eax |
57 |
|
|
jnz mts32_lw_asm_spec_acc |
58 |
|
|
|
59 |
|
|
/* L2 entry chained ? */ |
60 |
|
|
movl %esi, %eax |
61 |
|
|
andl $MTS_CHAIN_MASK, %eax |
62 |
|
|
jz 1f |
63 |
|
|
|
64 |
|
|
/* load L2 entry */ |
65 |
|
|
andl $0xfffffff0, %esi |
66 |
|
|
movl %edx, %eax |
67 |
|
|
shr $MTS32_OFFSET_BITS, %eax |
68 |
|
|
andl $((1 << MTS32_LEVEL2_BITS) - 1), %eax |
69 |
|
|
movl $((1 << MTS32_OFFSET_BITS) - 1), %ecx |
70 |
|
|
movl (%esi,%eax,4), %esi |
71 |
|
|
|
72 |
|
|
/* %esi = L2 entry */ |
73 |
|
|
movl %esi, %eax |
74 |
|
|
andl $MTS_ACC_MASK, %eax |
75 |
|
|
jnz mts32_lw_asm_spec_acc |
76 |
|
|
|
77 |
|
|
1: |
78 |
|
|
/* device access ? */ |
79 |
|
|
movl %esi, %eax |
80 |
|
|
andl $MTS_DEV_MASK, %eax |
81 |
|
|
jnz mts32_lw_asm_dev_acc |
82 |
|
|
|
83 |
|
|
/* raw memory access */ |
84 |
|
|
andl $0xfffffff0, %esi |
85 |
|
|
andl %edx, %ecx |
86 |
|
|
addl %ecx, %esi |
87 |
|
|
|
88 |
|
|
mts32_lw_asm_load_val: |
89 |
|
|
/* %esi = host address */ |
90 |
|
|
movl (%esi), %eax |
91 |
|
|
bswap %eax |
92 |
|
|
cdq |
93 |
|
|
|
94 |
|
|
/* %edx:%eax = sign-extended value */ |
95 |
|
|
lea CPU_GPR_OFS(%edi,%ebx,8), %esi |
96 |
|
|
movl %eax, (%esi) |
97 |
|
|
movl %edx, 4(%esi) |
98 |
|
|
|
99 |
|
|
popl %esi |
100 |
|
|
xorl %eax, %eax |
101 |
|
|
ret |
102 |
|
|
|
103 |
|
|
mts32_lw_asm_dev_acc: |
104 |
|
|
subl $8, %esp |
105 |
|
|
movl %esp, %eax |
106 |
|
|
|
107 |
|
|
pushl %eax /* data */ |
108 |
|
|
pushl $MTS_READ /* op_type = read */ |
109 |
|
|
pushl $4 /* op_size = 4 bytes */ |
110 |
|
|
|
111 |
|
|
/* %esi = entry, %ecx = shift, %edx = vaddr */ |
112 |
|
|
movl %esi, %eax |
113 |
|
|
andl $MTS_DEVID_MASK, %eax |
114 |
|
|
shr $MTS_DEVID_SHIFT, %eax |
115 |
|
|
andl %ecx, %edx |
116 |
|
|
andl $MTS_DEVOFF_MASK, %esi |
117 |
|
|
addl %edx, %esi |
118 |
|
|
|
119 |
|
|
pushl %esi /* haddr */ |
120 |
|
|
pushl %eax /* dev_id */ |
121 |
|
|
pushl %edi /* cpu */ |
122 |
|
|
|
123 |
|
|
/* call device access routine */ |
124 |
|
|
call _P(dev_access) |
125 |
|
|
addl $32, %esp |
126 |
|
|
|
127 |
|
|
/* %eax = haddr if raw access */ |
128 |
|
|
movl %eax, %esi |
129 |
|
|
testl %esi ,%esi |
130 |
|
|
jnz mts32_lw_asm_load_val |
131 |
|
|
|
132 |
|
|
movl -8(%esp), %eax |
133 |
|
|
cdq |
134 |
|
|
lea CPU_GPR_OFS(%edi,%ebx,8), %esi |
135 |
|
|
movl %eax, (%esi) |
136 |
|
|
movl %edx, 4(%esi) |
137 |
|
|
|
138 |
|
|
popl %esi |
139 |
|
|
xorl %eax, %eax |
140 |
|
|
ret |
141 |
|
|
|
142 |
|
|
mts32_lw_asm_spec_acc: |
143 |
|
|
/* %eax = mask */ |
144 |
|
|
subl $12, %esp |
145 |
|
|
movl %esp, %ecx |
146 |
|
|
|
147 |
|
|
movl $0, (%esp) /* clear exception */ |
148 |
|
|
|
149 |
|
|
pushl %ecx /* exception */ |
150 |
|
|
addl $4, %ecx |
151 |
|
|
pushl %ecx /* data */ |
152 |
|
|
|
153 |
|
|
pushl $4 /* op_size = 4 */ |
154 |
|
|
pushl $MTS_READ /* op_type = read */ |
155 |
|
|
pushl $MIPS_MEMOP_LW /* op_code = LW */ |
156 |
|
|
pushl %eax /* mask */ |
157 |
|
|
|
158 |
|
|
pushl %edx /* vaddr(lo) */ |
159 |
|
|
movl %edx, %eax |
160 |
|
|
cdq |
161 |
|
|
pushl %edx /* vaddr(hi) */ |
162 |
|
|
pushl %edi /* cpu */ |
163 |
|
|
call _P(mts_access_special) |
164 |
|
|
addl $((9*4)+12), %esp |
165 |
|
|
|
166 |
|
|
/* exception ? */ |
167 |
|
|
movl -12(%esp), %eax |
168 |
|
|
testl %eax, %eax |
169 |
|
|
jnz mts32_lw_asm_end |
170 |
|
|
|
171 |
|
|
/* save data */ |
172 |
|
|
movl -8(%esp), %eax |
173 |
|
|
cdq |
174 |
|
|
lea CPU_GPR_OFS(%edi,%ebx,8), %esi |
175 |
|
|
movl %eax, (%esi) |
176 |
|
|
movl %edx, 4(%esi) |
177 |
|
|
xorl %eax, %eax |
178 |
|
|
mts32_lw_asm_end: |
179 |
|
|
popl %esi |
180 |
|
|
ret |
181 |
|
|
|
182 |
|
|
/* |
183 |
|
|
* MTS64 Load Word (LW) fast version. |
184 |
|
|
* |
185 |
|
|
* Inputs: |
186 |
|
|
* %edi : cpu instance |
187 |
|
|
* %ebx : target register |
188 |
|
|
* %ecx:edx : virtual address |
189 |
|
|
*/ |
190 |
|
|
.globl _P(mts64_lw_asm) |
191 |
|
|
_P(mts64_lw_asm): |
192 |
|
|
/* Load entry from MTS64 cache */ |
193 |
|
|
movl %edx, %eax |
194 |
|
|
shr $MTS64_HASH_SHIFT, %edx |
195 |
|
|
andl $MTS64_HASH_MASK, %edx |
196 |
|
|
lea CPU_MTS64_CACHE_OFS(%edi,%edx,4), %esi |
197 |
|
|
|
198 |
|
|
/* %esi = entry pointer */ |
199 |
|
|
test %esi, %esi |
200 |
|
|
jz mts64_lw_slow_lookup |
201 |
|
|
|
202 |
|
|
/* Load entry start address in %eax */ |
203 |
|
|
lea (MTS64_ENTRY_START_OFS+4)(%esi), %eax |
204 |
|
|
|
205 |
|
|
ret |
206 |
|
|
|
207 |
|
|
mts64_lw_device_access: |
208 |
|
|
ret |
209 |
|
|
|
210 |
|
|
mts64_lw_slow_lookup: |
211 |
|
|
|
212 |
|
|
ret |