]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vi/special.c
fix ref822 again: remove uniqarray(), fix case with many entries in 'n'.
[plan9front.git] / sys / src / cmd / vi / special.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "mips.h"
7
8 void    Snor(ulong);
9 void    Ssll(ulong);
10 void    Ssra(ulong);
11 void    Sslt(ulong);
12 void    Ssltu(ulong);
13 void    Sand(ulong);
14 void    Saddu(ulong);
15 void    Sadd(ulong);
16 void    Sjr(ulong);
17 void    Sor(ulong);
18 void    Ssubu(ulong);
19 void    Sjalr(ulong);
20 void    Sdivu(ulong);
21 void    Smfhi(ulong);
22 void    Smflo(ulong);
23 void    Sxor(ulong);
24 void    Smult(ulong);
25 void    Smultu(ulong);
26 void    Sdiv(ulong);
27 void    Ssrl(ulong);
28 void    Ssllv(ulong);
29 void    Ssrlv(ulong);
30 void    Ssrav(ulong);
31
32 Inst ispec[] = 
33 {
34         { Ssll,         "sll",  Iarith },
35         { undef,                "" },
36         { Ssrl,         "srl",  Iarith },
37         { Ssra,         "sra",  Iarith },
38         { Ssllv,        "sllv", Iarith },
39         { undef,        "" },
40         { Ssrlv,        "srlv", Iarith },
41         { Ssrav,        "srav", Iarith },
42         { Sjr,          "jr",   Ibranch },
43         { Sjalr,        "jalr", Ibranch },
44         { undef,        "" },
45         { undef,        "" },
46         { Ssyscall,     "sysc", Isyscall },
47         { undef,        "" },
48         { undef,        "" },
49         { undef,        "" },
50         { Smfhi,        "mfhi", Ireg },
51         { undef,        "" },
52         { Smflo,        "mflo", Ireg },
53         { undef,        "" },
54         { undef,        "" },
55         { undef,        "" },
56         { undef,        "" },
57         { undef,        "" },
58         { Smult,        "mult", Iarith },
59         { Smultu,       "multu" },
60         { Sdiv,         "div",  Iarith },
61         { Sdivu,        "divu", Iarith },
62         { undef,        "" },
63         { undef,        "" },
64         { undef,        "" },
65         { undef,        "" },
66         { Sadd,         "add",  Iarith },
67         { Saddu,        "addu", Iarith },
68         { undef,        "" },
69         { Ssubu,        "subu", Iarith },
70         { Sand,         "and",  Iarith },
71         { Sor,          "or",   Iarith },
72         { Sxor,         "xor",  Iarith },
73         { Snor,         "nor",  Iarith },
74         { undef,        "" },
75         { undef,        "" },
76         { Sslt,         "slt",  Iarith },
77         { Ssltu,        "sltu", Iarith },
78         { undef,        "" },
79         { undef,        "" },
80         { undef,        "" },
81         { undef,        "" },
82         { undef,        "" },
83         { undef,        "" },
84         { undef,        "" },
85         { undef,        "" },
86         { undef,        "" },
87         { undef,        "" },
88         { undef,        "" },
89         { undef,        "" },
90         { undef,        "" },
91         { undef,        "" },
92         { undef,        "" },
93         { undef,        "" },
94         { undef,        "" },
95         { undef,        "" },
96         { undef,        "" },
97         { undef,        "" },
98         { 0 }
99 };
100
101 void
102 Ispecial(ulong inst)
103 {
104         Inst *i;
105
106         i = &ispec[inst&0x3f];
107         reg.ip = i;
108         i->count++;
109         (*i->func)(inst);
110 }
111
112 void
113 Snor(ulong inst)
114 {
115         int rs, rt, rd;
116
117         Get3(rs, rt, rd, inst);
118         if(trace)
119                 itrace("nor\tr%d,r%d,r%d", rd, rs, rt);
120
121         if(inst == INOP)
122                 nopcount++;
123         else
124                 reg.r[rd] = ~(reg.r[rt]|reg.r[rs]);
125 }
126
127 void
128 Ssll(ulong inst)
129 {
130         int rd, rt, shamt;
131
132         SpecialGetrtrd(rt, rd, inst);
133         shamt = (inst>>6)&0x1f;
134         if(trace)
135                 itrace("sll\tr%d,r%d,%d", rd, rt, shamt);
136
137         reg.r[rd] = reg.r[rt]<<shamt;
138 }
139
140 void
141 Ssllv(ulong inst)
142 {
143         int rd, rt, rs;
144
145         Get3(rs, rt, rd, inst);
146         if(trace)
147                 itrace("sllv\tr%d,r%d,r%d", rd, rt, rs);
148
149         reg.r[rd] = reg.r[rt]<<(reg.r[rs]&0x1f);
150 }
151
152 void
153 Ssrlv(ulong inst)
154 {
155         int rd, rt, rs;
156
157         Get3(rs, rt, rd, inst);
158         if(trace)
159                 itrace("srlv\tr%d,r%d,r%d", rd, rt, rs);
160
161         reg.r[rd] = (ulong)reg.r[rt] >> (reg.r[rs]&0x1f);
162 }
163
164 void
165 Ssrav(ulong inst)
166 {
167         int rd, rt, rs, shamt;
168
169         Get3(rs, rt, rd, inst);
170         if(trace)
171                 itrace("srav\tr%d,r%d,r%d", rd, rt, rs);
172
173         shamt = reg.r[rs]&0x1f;
174         if(shamt != 0 && (reg.r[rt] & SIGNBIT))
175                 reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
176         else
177                 reg.r[rd] = reg.r[rt]>>shamt;
178 }
179
180 void
181 Ssrl(ulong inst)
182 {
183         int rd, rt, shamt;
184
185         SpecialGetrtrd(rt, rd, inst);
186         shamt = (inst>>6)&0x1f;
187         if(trace)
188                 itrace("srl\tr%d,r%d,%d", rd, rt, shamt);
189
190         reg.r[rd] = (ulong)reg.r[rt] >> shamt;
191 }
192
193 void
194 Ssra(ulong inst)
195 {
196         int rd, rt, shamt;
197
198         SpecialGetrtrd(rt, rd, inst);
199         shamt = (inst>>6)&0x1f;
200         if(trace)
201                 itrace("sra\tr%d,r%d,%d", rd, rt, shamt);
202
203         if(shamt != 0 && (reg.r[rt] & SIGNBIT))
204                 reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
205         else
206                 reg.r[rd] = reg.r[rt]>>shamt;
207 }
208
209 void
210 Sslt(ulong inst)
211 {
212         int rs, rt, rd;
213
214         Get3(rs, rt, rd, inst);
215         if(trace)
216                 itrace("slt\tr%d,r%d,r%d", rd, rs, rt);
217
218         reg.r[rd] = reg.r[rs] < reg.r[rt] ? 1 : 0;
219 }
220
221 void
222 Ssltu(ulong inst)
223 {
224         int rs, rt, rd;
225
226         Get3(rs, rt, rd, inst);
227         if(trace)
228                 itrace("sltu\tr%d,r%d,r%d", rd, rs, rt);
229
230         reg.r[rd] = (unsigned)reg.r[rs] < (unsigned)reg.r[rt] ? 1 : 0;
231 }
232
233 void
234 Sand(ulong inst)
235 {
236         int rs, rt, rd;
237
238         Get3(rs, rt, rd, inst);
239         if(trace)
240                 itrace("and\tr%d,r%d,r%d", rd, rs, rt);
241
242         reg.r[rd] = reg.r[rs] & reg.r[rt];
243 }
244
245 void
246 Saddu(ulong inst)
247 {
248         int rs, rt, rd;
249
250         Get3(rs, rt, rd, inst);
251         if(trace)
252                 itrace("addu\tr%d,r%d,r%d", rd, rs, rt);
253
254         reg.r[rd] = reg.r[rs] + reg.r[rt];
255 }
256
257 void
258 Sadd(ulong inst)
259 {
260         int rs, rt, rd;
261
262         Get3(rs, rt, rd, inst);
263         if(trace)
264                 itrace("add\tr%d,r%d,r%d", rd, rs, rt);
265
266         reg.r[rd] = reg.r[rs] + reg.r[rt];
267 }
268
269 void
270 Ssubu(ulong inst)
271 {
272         int rs, rt, rd;
273
274         Get3(rs, rt, rd, inst);
275         if(trace)
276                 itrace("subu\tr%d,r%d,r%d", rd, rs, rt);
277
278         reg.r[rd] = reg.r[rs] - reg.r[rt];
279 }
280
281 void
282 Sor(ulong inst)
283 {
284         int rs, rt, rd;
285
286         Get3(rs, rt, rd, inst);
287         if(trace)
288                 itrace("or\tr%d,r%d,r%d", rd, rs, rt);
289
290         reg.r[rd] = reg.r[rs] | reg.r[rt];
291 }
292
293 void
294 Sxor(ulong inst)
295 {
296         int rs, rt, rd;
297
298         Get3(rs, rt, rd, inst);
299         if(trace)
300                 itrace("or\tr%d,r%d,r%d", rd, rs, rt);
301
302         reg.r[rd] = reg.r[rs] ^ reg.r[rt];
303 }
304
305 void
306 Sjr(ulong inst)
307 {
308         ulong npc;
309         int rs;
310         Symbol s;
311
312         rs = (inst>>21)&0x1f;
313         npc = reg.r[rs];
314
315         if(trace)
316                 itrace("jr\t0x%lux", npc);
317
318         /* Do the delay slot */
319         reg.ir = ifetch(reg.pc+4);
320         Statbra();
321         Iexec(reg.ir);
322         if(calltree) {
323                 if(rs == 31 || rs == 2) {
324                         findsym(npc, CTEXT, &s);
325                         Bprint(bioout, "%8lux return to %lux %s r1=%lux\n",
326                                                 reg.pc, npc, s.name, reg.r[1]);
327                 }
328         }
329         reg.pc = npc-4;
330 }
331
332 void
333 Sjalr(ulong inst)
334 {
335         ulong npc;
336         int rs, rd;
337         Symbol s;
338
339         rs = (inst>>21)&0x1f;
340         rd = (inst>>11)&0x1f;
341         npc = reg.r[rs];
342
343         if(trace)
344                 itrace("jalr\tr%d,r%d", rd, rs);
345
346         reg.r[rd] = reg.pc+8;
347         /* Do the delay slot */
348         reg.ir = ifetch(reg.pc+4);
349         Statbra();
350         Iexec(reg.ir);
351
352         if(calltree) {
353                 findsym(npc, CTEXT, &s);
354                 if(rs == 31)
355                         Bprint(bioout, "%8lux return to %8lux %s\n",
356                                                 reg.pc, npc, s.name);
357                 else {
358                         printparams(&s, reg.r[29]);
359                         Bputc(bioout, '\n');
360                 }
361         }
362
363         reg.pc = npc-4;
364 }
365
366 void
367 Sdivu(ulong inst)
368 {
369         int rs, rt;
370
371         Getrsrt(rs,rt,inst);
372         if(trace)
373                 itrace("divu\tr%d,r%d", rs, rt);
374
375         reg.mlo = (ulong)reg.r[rs]/(ulong)reg.r[rt];
376         reg.mhi = (ulong)reg.r[rs]%(ulong)reg.r[rt];
377 }
378
379 void
380 Sdiv(ulong inst)
381 {
382         int rs, rt;
383
384         Getrsrt(rs,rt,inst);
385         if(trace)
386                 itrace("div\tr%d,r%d", rs, rt);
387
388         reg.mlo = reg.r[rs]/reg.r[rt];
389         reg.mhi = reg.r[rs]%reg.r[rt];
390 }
391
392 void
393 Smfhi(ulong inst)
394 {
395         int rd;
396
397         rd = (inst>>11)&0x1ff;
398         if(trace)
399                 itrace("mfhi\tr%d", rd);
400
401         reg.r[rd] = reg.mhi;
402 }
403
404 void
405 Smflo(ulong inst)
406 {
407         int rd;
408
409         rd = (inst>>11)&0x1ff;
410         if(trace)
411                 itrace("mflo\tr%d", rd);
412
413         reg.r[rd] = reg.mlo;
414 }
415
416 void
417 Smult(ulong inst)
418 {
419         int rs, rt;
420         Mul m;
421
422         Getrsrt(rs,rt,inst);
423         if(trace)
424                 itrace("mult\tr%d,r%d", rs,rt);
425
426         m = mul(reg.r[rs], reg.r[rt]);
427         reg.mlo = m.lo;
428         reg.mhi = m.hi;
429 }
430
431 void
432 Smultu(ulong inst)
433 {
434         int rs, rt;
435         Mulu m;
436
437         Getrsrt(rs,rt,inst);
438         if(trace)
439                 itrace("multu\tr%d,r%d", rs,rt);
440
441         m = mulu(reg.r[rs], reg.r[rt]);
442         reg.mlo = m.lo;
443         reg.mhi = m.hi;
444 }