-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.s
333 lines (281 loc) · 7.47 KB
/
utils.s
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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#define c_print_int 1
#define c_print_str 4
#define c_atoi 5
#define c_sbrk 9
#define c_exit 10
#define c_print_char 11
#define c_openFile 13
#define c_readFile 14
#define c_writeFile 15
#define c_closeFile 16
#define c_exit2 17
#define c_fflush 18
#define c_feof 19
#define c_ferror 20
#define c_printHex 34
# ecall wrappers
.globl print_int, print_str, atoi, sbrk, exit, print_char, fopen, fread, fwrite, fclose, exit2, fflush, ferror, print_hex
# helper functions
.globl file_error, print_int_array, malloc
.data
error_string: .string "This library file should not be directly called!"
.text
# Exits if you run this file
main:
la a1 error_string
jal print_str
li a1 1
jal exit2
# End main
#================================================================
# void print_int(int a1)
# Prints the integer in a1.
# args:
# a1 = integer to print
# return:
# void
#================================================================
print_int:
li a0 c_print_int
ecall
jr ra
#================================================================
# void print_str(char *a1)
# Prints the null-terminated string at address a1.
# args:
# a1 = address of the string you want printed.
# return:
# void
#================================================================
print_str:
li a0 c_print_str
ecall
jr ra
#================================================================
# int atoi(char* a1)
# Returns the integer version of the string at address a1.
# args:
# a1 = address of the string you want to turn into an integer.
# return:
# a0 = Integer representation of string
#================================================================
atoi:
li a0 c_atoi
ecall
jr ra
#================================================================
# void *sbrk(int a1)
# Allocates a1 bytes onto the heap.
# args:
# a1 = Number of bytes you want to allocate.
# return:
# a0 = Pointer to the start of the allocated memory
#================================================================
sbrk:
li a0 c_sbrk
ecall
jr ra
#================================================================
# void noreturn exit()
# Exits the program with a zero exit code.
# args:
# None
# return:
# No Return
#================================================================
exit:
li a0 c_exit
ecall
#================================================================
# void print_char(char a1)
# Prints the ASCII character in a1 to the console.
# args:
# a1 = character to print
# return:
# void
#================================================================
print_char:
li a0 c_print_char
ecall
jr ra
#================================================================
# int fopen(char *a1, int a2)
# Opens file with name a1 with permissions a2.
# args:
# a1 = filepath
# a2 = permissions (0, 1, 2, 3, 4, 5 = r, w, a, r+, w+, a+)
# return:
# a0 = file descriptor
#================================================================
fopen:
li a0 c_openFile
ecall
jr ra
#================================================================
# int fread(int a1, void *a2, size_t a3)
# Reads a3 bytes of the file into the buffer a2.
# args:
# a1 = file descriptor
# a2 = pointer to the buffer you want to write the read bytes to.
# a3 = Number of bytes to be read.
# return:
# a0 = Number of bytes actually read.
#================================================================
fread:
li a0 c_readFile
ecall
jr ra
#================================================================
# int fwrite(int a1, void *a2, size_t a3, size_t a4)
# Writes a3 * a4 bytes from the buffer in a2 to the file descriptor a1.
# args:
# a1 = file descriptor
# a2 = Buffer to read from
# a3 = Number of items to read from the buffer.
# a4 = Size of each item in the buffer.
# return:
# a0 = Number of elements writen. If this is less than a3,
# it is either an error or EOF. You will also need to still flush the fd.
#================================================================
fwrite:
li a0 c_writeFile
ecall
jr ra
#================================================================
# int fclose(int a1)
# Closes the file descriptor a1.
# args:
# a1 = file descriptor
# return:
# a0 = 0 on success, and EOF (-1) otherwise.
#================================================================
fclose:
li a0 c_closeFile
ecall
jr ra
#================================================================
# void noreturn exit2(int a1)
# Exits the program with error code a1.
# args:
# a1 = Exit code.
# return:
# This program does not return.
#================================================================
exit2:
li a0 c_exit2
ecall
jr ra
#================================================================
# int fflush(int a1)
# Flushes the data to the filesystem.
# args:
# a1 = file descriptor
# return:
# a0 = 0 on success, and EOF (-1) otherwise.
#================================================================
fflush:
li a0 c_fflush
ecall
jr ra
#================================================================
# int ferror(int a1)
# Returns a nonzero value if the file stream has errors, otherwise it returns 0.
# args:
# a1 = file descriptor
# return:
# a0 = Nonzero falue if the end of file is reached. 0 Otherwise.
#================================================================
ferror:
li a0 c_ferror
ecall
jr ra
#================================================================
# void print_hex(int a1)
#
# args:
# a1 = The word which will be printed as a hex value.
# return:
# void
#================================================================
print_hex:
li a0 c_printHex
ecall
jr ra
#================================================================
# void* malloc(int a0)
# Allocates heap memory and return a pointer to it
# args:
# a0 is the # of bytes to allocate heap memory for
# return:
# a0 is the pointer to the allocated heap memory
#================================================================
malloc:
# Call to sbrk
mv a1 a0
addi a0 x0 9
ecall
jr ra
#================================================================
# void print_int_array(int* a0, int a1, int a2)
# Prints an integer array, with spaces between the elements
# args:
# a0 is the pointer to the start of the array
# a1 is the # of rows in the array
# a2 is the # of columns in the array
# return:
# void
#================================================================
print_int_array:
# Prologue
addi sp sp -24
sw s0 0(sp)
sw s1 4(sp)
sw s2 8(sp)
sw s3 12(sp)
sw s4 16(sp)
sw ra 20(sp)
# Save arguments
mv s0 a0
mv s1 a1
mv s2 a2
# Set outer loop index
li s3 0
outer_loop_start:
# Check outer loop condition
beq s3 s1 outer_loop_end
# Set inner loop index
li s4 0
inner_loop_start:
# Check inner loop condition
beq s4 s2 inner_loop_end
# t0 = row index * len(row) + column index
mul t0 s2 s3
add t0 t0 s4
slli t0 t0 2
# Load matrix element
add t0 t0 s0
lw t1 0(t0)
# Print matrix element
mv a1 t1
jal print_int
# Print whitespace
li a1 ' '
jal print_char
addi s4 s4 1
j inner_loop_start
inner_loop_end:
# Print newline
li a1 '\n'
jal print_char
addi s3 s3 1
j outer_loop_start
outer_loop_end:
# Epilogue
lw s0 0(sp)
lw s1 4(sp)
lw s2 8(sp)
lw s3 12(sp)
lw s4 16(sp)
lw ra 20(sp)
addi sp sp 24
jr ra