solo_asms.s
5.22 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
* Copyright (C) 1996-1998 by the Board of Trustees
* of Leland Stanford Junior University.
*
* This file is part of the SimOS distribution.
* See LICENSE file for terms of the license.
*
*/
/*****************************************************************
* solo_asms.s
*
* Assembly routines needed by solo MIPSY. Solo mipsy currently works
* by linking directly into an application. This only works in
* uniprocessor mode right now.
*****************************************************************/
#include <asm.h>
#include <regdef.h>
#include <sys.s>
#include "mips_arch.h"
/*
* StartApp(int argc, char *argv[], int environLen, char *environ[],
* void *newStackPtr)
* Setup the stack as if the kernel does during an exec and then
* jump to the entry point.
*/
LEAF(SetupStack)
/*
* t4 will hold the simulated stack pointer
*/
lw t4,16(sp)
/*
* Compute the size of the stack as
* ((argc + numEnv)*4 + 64) & ~7;
*/
addu t0,a0,a2
mul t0,t0,4
addu t0,t0,64
and t0,t0,-8
subu t4,t4,t0
/*
*
* Build the stack as
*
* environ Array
* argv Array
* argc
*/
sw a0,0(t4)
addu t2,t4,4
/*
* Copy argv including null pointer.
*/
1:
lw t1,0(a1)
sw t1,0(t2)
addu a1,a1,4
addu t2,t2,4
bne t1,0, 1b
/*
* Copy environ include null pointer.
*/
2:
lw t1,0(a3)
sw t1,0(t2)
addu a3,a3,4
addu t2,t2,4
bne t1,0, 2b
.set noreorder
addi v0, t4, 0
nop
j ra
.set noreorder
END(StartApp)
#ifdef NOTDEF
/* Not using this anymore */
/*****************************************************************
* SoloMipsyEnter
*
* Store needed registers into the simulator's structure.
* Set the stack pointer with room for the simulator's stack.
* Jump into the simulation with the return address being the first
* instruction to start simulating.
*
* a0 - Pointer to mipsy's register file
* a1 - Function to jump to when the regs are saved
*****************************************************************/
.text
.align 4
.extern holdSP 32
.align 4
.extern holdRA 32
.align 4
.extern holdGP 32
.align 4
.extern holdPE 32
LEAF(SoloMipsyEnter)
XLEAF(solomipsyenter_)
/* Store the callers registers in Mipsy's register
file (loaded into a0) */
la a0, PE
sw s0, REG_S0*4(a0)
sw s1, REG_S1*4(a0)
sw s2, REG_S2*4(a0)
sw s3, REG_S3*4(a0)
sw s4, REG_S4*4(a0)
sw s5, REG_S5*4(a0)
sw s6, REG_S6*4(a0)
sw s7, REG_S7*4(a0)
sw ra, REG_RA*4(a0)
sw gp, REG_GP*4(a0)
sw sp, REG_SP*4(a0) /* Simulated stack */
sw s8, REG_FP*4(a0) /* Another name for fp */
s.d $f0, REG_FPR_0(a0)
s.d $f2, REG_FPR_2(a0)
s.d $f4, REG_FPR_4(a0)
s.d $f6, REG_FPR_6(a0)
s.d $f8, REG_FPR_8(a0)
s.d $f10, REG_FPR_10(a0)
s.d $f12, REG_FPR_12(a0)
s.d $f14, REG_FPR_14(a0)
s.d $f16, REG_FPR_16(a0)
s.d $f18, REG_FPR_18(a0)
lw sp, mipsyStackTop
lui s0, 0xffff
ori s0, s0, 0xfff8
and sp, s0, sp
la a0, PE
/* Original ra - the instruction after the MipsyStart() */
lw ra, REG_RA*4(a0)
/* Set the pc to return to the caller */
la t0, StartSimLabel
sw t0, REG_PC*4(a0)
addi t0, 4
sw t0, REG_NPC*4(a0)
/* Now call the simulator - a0 still has the registers */
.set noreorder
la a1, SoloRun
la t9, SoloRun
nop
jal a1
nop
.set reorder
END(SoloMipsyEnter)
StartSimLabel:
.set noreorder
nop
j ra
nop
.set reorder
#endif /* NOT DEF */
/*****************************************************************
* MipsyHandleSyscall
*
*****************************************************************/
/* Until I figure out exactly which registers are needed, I'll save */
/* every register */
LEAF(MipsyHandleSyscall)
sw sp, holdSP
sw ra, holdRA
sw a0, holdPE
sw gp, holdGP
move t0, a0
lw v1, REG_V1*4(t0)
lw v0, REG_V0*4(t0)
lw a0, REG_A0*4(t0)
lw a1, REG_A1*4(t0)
lw a2, REG_A2*4(t0)
lw a3, REG_A3*4(t0)
lw gp, REG_GP*4(t0)
lw sp, REG_SP*4(t0)
/* Test if this was an exit call */
li t1, 1001
beq t1, v0, ExitLabel
.set noreorder
lw v0, REG_V0*4(t0)
syscall
.set reorder
lw t0, holdPE
sw v0, REG_V0*4(t0)
sw v1, REG_V1*4(t0)
sw a0, REG_A0*4(t0)
sw a1, REG_A1*4(t0)
sw a2, REG_A2*4(t0)
sw a3, REG_A3*4(t0)
sw sp, REG_SP*4(t0)
lw gp, holdGP
lw sp, holdSP
lw ra, holdRA
j ra
ExitLabel:
jal SoloExit
.set noreorder
nop
lw sp, holdSP
lw ra, holdRA
nop
j ra
.set reorder
END(MipsyHandleSyscall)
/* Optimization for the page hash function. Everything is currently hardcoded
so be careful. The input is a unsigned long long in registers a0 and a1, and
the output is an unsigned in register v0. This is big endian, so a0 holds the
high order bits of the address. This routine is written for a page size of
4k (shift right 12 bits) and a hash mapping that takes the low order 13 bits
(8192 buckets). */
LEAF(mapping_hash)
srl a1, a1, 12
sll a0, a0, 20
or v0, a0, a1
andi v0, v0, 0x00001fff
j ra
END(mapping_hash)