123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mach.h>
- #define Extern extern
- #include "sparc.h"
- void
- ldf(ulong ir)
- {
- ulong ea;
- int rd, rs1, rs2;
- getrop23(ir);
- if(ir&IMMBIT) {
- ximm(ea, ir);
- if(trace)
- itrace("ldf\tf%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
- ea += reg.r[rs1];
- }
- else {
- ea = reg.r[rs1] + reg.r[rs2];
- if(trace)
- itrace("ldf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
- }
- reg.di[rd] = getmem_w(ea);
- }
- void
- lddf(ulong ir)
- {
- ulong ea;
- int rd, rs1, rs2;
- getrop23(ir);
- if(ir&IMMBIT) {
- ximm(ea, ir);
- if(trace)
- itrace("lddf\tf%d,0x%lux(r%d) ea=%lux",
- rd, ea, rs1, ea+reg.r[rs1]);
- ea += reg.r[rs1];
- }
- else {
- ea = reg.r[rs1] + reg.r[rs2];
- if(trace)
- itrace("lddf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
- }
- if(ea&7) {
- Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", ea);
- longjmp(errjmp, 0);
- }
- if(rd&1)
- undef(ir);
- reg.di[rd] = getmem_w(ea);
- reg.di[rd+1] = getmem_w(ea+4);
- }
- void
- stf(ulong ir)
- {
- ulong ea;
- int rd, rs1, rs2;
- getrop23(ir);
- if(ir&IMMBIT) {
- ximm(ea, ir);
- if(trace)
- itrace("stf\tf%d,0x%lux(r%d) %lux=%g",
- rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
- ea += reg.r[rs1];
- }
- else {
- ea = reg.r[rs1] + reg.r[rs2];
- if(trace)
- itrace("stf\tf%d,[r%d+r%d] %lux=%lux",
- rd, rs1, rs2, ea, reg.r[rd]);
- }
- putmem_w(ea, reg.di[rd]);
- }
- void
- stdf(ulong ir)
- {
- ulong ea;
- int rd, rs1, rs2;
- getrop23(ir);
- if(ir&IMMBIT) {
- ximm(ea, ir);
- if(trace)
- itrace("stdf\tf%d,0x%lux(r%d) %lux=%g",
- rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
- ea += reg.r[rs1];
- }
- else {
- ea = reg.r[rs1] + reg.r[rs2];
- if(trace)
- itrace("stdf\tf%d,[r%d+r%d] %lux=%lux",
- rd, rs1, rs2, ea, reg.r[rd]);
- }
- if(ea&7) {
- Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", ea);
- longjmp(errjmp, 0);
- }
- if(rd&1)
- undef(ir);
- putmem_w(ea, reg.di[rd]);
- putmem_w(ea+4, reg.di[rd+1]);
- }
- void
- fcmp(ulong ir)
- {
- int fc, rd, rs1, rs2;
- getrop23(ir);
- USED(rd);
- SET(fc);
- switch((ir>>5)&0x1FF) {
- default:
- undef(ir);
- case 0x51: /* fcmps */
- if(trace)
- itrace("fcmps\tf%d,f%d", rs1, rs2);
- if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
- fc = 3;
- break;
- }
- if(reg.fl[rs1] == reg.fl[rs2]) {
- fc = 0;
- break;
- }
- if(reg.fl[rs1] < reg.fl[rs2]) {
- fc = 1;
- break;
- }
- if(reg.fl[rs1] > reg.fl[rs2]) {
- fc = 2;
- break;
- }
- print("ki: fcmp error\n");
- break;
- case 0x52:
- if(trace)
- itrace("fcmpd\tf%d,f%d", rs1, rs2);
- rs1 >>= 1;
- rs2 >>= 1;
- if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
- fc = 3;
- break;
- }
- if(reg.fd[rs1] == reg.fd[rs2]) {
- fc = 0;
- break;
- }
- if(reg.fd[rs1] < reg.fd[rs2]) {
- fc = 1;
- break;
- }
- if(reg.fd[rs1] > reg.fd[rs2]) {
- fc = 2;
- break;
- }
- print("ki: fcmp error\n");
- break;
- case 0x55: /* fcmpes */
- if(trace)
- itrace("fcmpes\tf%d,f%d", rs1, rs2);
- rs1 >>= 1;
- rs2 >>= 2;
- if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
- Bprint(bioout, "invalid_fp_register\n");
- longjmp(errjmp, 0);
- }
- if(reg.fl[rs1] == reg.fl[rs2]) {
- fc = 0;
- break;
- }
- if(reg.fl[rs1] < reg.fl[rs2]) {
- fc = 1;
- break;
- }
- if(reg.fl[rs1] > reg.fl[rs2]) {
- fc = 2;
- break;
- }
- print("ki: fcmp error\n");
- break;
- case 0x56:
- if(trace)
- itrace("fcmped\tf%d,f%d", rs1, rs2);
- if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
- Bprint(bioout, "invalid_fp_register\n");
- longjmp(errjmp, 0);
- }
- if(reg.fd[rs1] == reg.fd[rs2]) {
- fc = 0;
- break;
- }
- if(reg.fd[rs1] < reg.fd[rs2]) {
- fc = 1;
- break;
- }
- if(reg.fd[rs1] > reg.fd[rs2]) {
- fc = 2;
- break;
- }
- print("ki: fcmp error\n");
- break;
- }
- reg.fpsr = (reg.fpsr&~(0x3<<10)) | (fc<<10);
- }
- void
- fbcc(ulong ir)
- {
- char *op;
- ulong npc;
- int takeit, fc, ba, anul;
- fc = (reg.fpsr>>10)&3;
- ba = 0;
- SET(op, takeit);
- switch((ir>>25)&0x0F) {
- case 0:
- op = "fbn";
- takeit = 0;
- break;
- case 1:
- op = "fbne";
- takeit = fc == FP_L || fc == FP_G || fc == FP_U;
- break;
- case 2:
- op = "fblg";
- takeit = fc == FP_L || fc == FP_G;
- break;
- case 3:
- op = "fbul";
- takeit = fc == FP_L || fc == FP_U;
- break;
- case 4:
- op = "fbl";
- takeit = fc == FP_L;
- break;
- case 5:
- op = "fbug";
- takeit = fc == FP_U || fc == FP_G;
- break;
- case 6:
- op = "fbg";
- takeit = fc == FP_G;
- break;
- case 7:
- op = "fbu";
- takeit = fc == FP_U;
- break;
- case 8:
- op = "fba";
- ba = 1;
- takeit = 1;
- break;
- case 9:
- op = "fbe";
- takeit = fc == FP_E;
- break;
- case 10:
- op = "fbue";
- takeit = fc == FP_E || fc == FP_U;
- break;
- case 11:
- op = "fbge";
- takeit = fc == FP_E || fc == FP_G;
- break;
- case 12:
- op = "fbuge";
- takeit = fc == FP_E || fc == FP_G || fc == FP_U;
- break;
- case 13:
- op = "fble";
- takeit = fc == FP_E || fc == FP_L;
- break;
- case 14:
- op = "fbule";
- takeit = fc == FP_E || fc == FP_L || fc == FP_U;
- break;
- case 15:
- op = "fbo";
- takeit = fc == FP_E || fc == FP_L || fc == FP_G;
- break;
- }
- npc = ir & 0x3FFFFF;
- if(npc & (1<<21))
- npc |= ~((1<<22)-1);
- npc = (npc<<2) + reg.pc;
- anul = ir&ANUL;
- if(trace) {
- if(anul)
- itrace("%s,a\t%lux", op, npc);
- else
- itrace("%s\t%lux", op, npc);
- }
- if(takeit == 0) {
- reg.pc += 4;
- if(anul == 0) {
- reg.ir = ifetch(reg.pc);
- delay(reg.pc+4);
- }
- else
- anulled++;
- return;
- }
- ci->taken++;
- if(ba && anul) {
- reg.pc = npc-4;
- anulled++;
- return;
- }
- reg.ir = ifetch(reg.pc+4);
- delay(npc);
- reg.pc = npc-4;
- }
- void
- farith(ulong ir)
- {
- char *op;
- long v;
- int rd, rs1, rs2, fmt;
- fmt = 0;
- getrop23(ir);
- switch((ir>>5)&0x1FF) {
- default:
- undef(ir);
- case 0x41:
- reg.fl[rd] = reg.fl[rs1] + reg.fl[rs2];
- op = "fadds";
- break;
- case 0x42:
- reg.fd[rd>>1] = reg.fd[rs1>>1] + reg.fd[rs2>>1];
- op = "faddd";
- break;
- case 0x45:
- reg.fl[rd] = reg.fl[rs1] - reg.fl[rs2];
- op = "fsubs";
- break;
- case 0x46:
- reg.fd[rd>>1] = reg.fd[rs1>>1] - reg.fd[rs2>>1];
- op = "fsubd";
- break;
- case 0x4d:
- if(reg.fl[rs2] == 0.0) {
- Bprint(bioout, "fp_exception DZ\n");
- longjmp(errjmp, 0);
- }
- reg.fl[rd] = reg.fl[rs1] / reg.fl[rs2];
- op = "fdivs";
- break;
- case 0x4e:
- if(reg.fd[rs2>>1] == 0.0) {
- Bprint(bioout, "fp_exception DZ\n");
- longjmp(errjmp, 0);
- }
- reg.fd[rd>>1] = reg.fd[rs1>>1] / reg.fd[rs2>>1];
- op = "fdivd";
- break;
- case 0x49:
- reg.fl[rd] = reg.fl[rs1] * reg.fl[rs2];
- op = "fmuls";
- break;
- case 0x4a:
- reg.fd[rd>>1] = reg.fd[rs1>>1] * reg.fd[rs2>>1];
- op = "fmuld";
- break;
- case 0xc4:
- reg.fl[rd] = (long)reg.di[rs2];
- fmt = 1;
- op = "fitos";
- break;
- case 0xc8:
- reg.fd[rd>>1] = (long)reg.di[rs2];
- fmt = 1;
- op = "fitod";
- break;
- case 0xd1:
- v = reg.fl[rs2];
- reg.di[rd] = v;
- fmt = 1;
- op = "fstoi";
- break;
- case 0xd2:
- v = reg.fd[rs2>>1];
- reg.di[rd] = v;
- fmt = 1;
- op = "fdtoi";
- break;
- case 0x01:
- reg.di[rd] = reg.di[rs2];
- fmt = 1;
- op = "fmovs";
- break;
- case 0x05:
- reg.fl[rd] = -reg.fl[rs2];
- fmt = 1;
- op = "fnegs";
- break;
- case 0x09:
- reg.fl[rd] = fabs(reg.fl[rs2]);
- fmt = 1;
- op = "fabss";
- break;
- case 0xc9:
- reg.fd[rd>>1] = reg.fl[rs2];
- fmt = 1;
- op = "fstod";
- break;
- case 0xc6:
- reg.fl[rd] = reg.fd[rs2>>1];
- fmt = 1;
- op = "fdtos";
- break;
- }
- if(trace) {
- switch(fmt) {
- case 0:
- itrace("%s\tf%d,f%d,f%d", op, rs1, rs2, rd);
- break;
- case 1:
- itrace("%s\tf%d,f%d", op, rs2, rd);
- break;
- }
- }
- }
|