acl4のページ0014

(1)

(2) a4_0014.c

#if (a_Version >= 2)
    #define BufFree                     a_BufFree
    #define BufFree_ini                 a_BufFree_ini
    #define BufFree_din                 a_BufFree_din
    #define BufFree_add                 a_BufFree_add
    #define BufFree_malloc              a_BufFree_malloc
    #define BufFree_flush               a_BufFree_flush
    #define double2intptr               a_double2intptr
    #define A4vm_exec0                  a_A4vm_exec0
#endif

a_class(a_BufFree) { a_VecChr stk[1]; };
a_static void a_BufFree_ini(a_BufFree *w) { a_VecChr_ini(w->stk); }
a_static void a_BufFree_din(a_BufFree *w) { a_VecChr_din(w->stk); }

a_static void a_BufFree_add(a_BufFree *w, void *p, intptr_t sz)
{
    void **t = a_VecChr_stkAdd(w->stk, 2 * sizeof (void *));
    t[0] = p; t[1] = (void *) sz;
}

a_static void *a_BufFree_malloc(a_BufFree *w, intptr_t sz)
{
    void *p = a_malloc(_arg_  sz); a_BufFree_add(w, p, sz); return p;
}

a_static void a_BufFree_flush(a_BufFree *w)
{
    while (w->stk->n > 0) {
        w->stk->n -= 2 * sizeof (void *);
        void **t = (void **) (w->stk->p + w->stk->n);
        a_free(_arg_  t[0], (intptr_t) t[1]);
    }
}

// 切り捨てではなく四捨五入.
a_static intptr_t a_double2intptr(double x) { if (x >= 0.0) { x += 0.5; } else { x -= 0.5; } return (intptr_t) x; }

a_class(a_A4vm_exec0_funcInfo) {
    intptr_t prv, reg, frg, subArg, pc, arg;
};

a_static intptr_t a_A4vm_exec0(intptr_t *bp, intptr_t bn, intptr_t argc, intptr_t *argv)
{
    a_VecChr vcLbl[1], vcInf[1], vcStk[1]; a_VecChr_ini4(vcLbl, vcInf, vcStk, 0);
    a_VecChr_reserve(vcLbl, 256 * sizeof (intptr_t));
    intptr_t argc1 = (argc + 1) & -2;
    a_VecChr_reserve(vcStk, argc1 * sizeof (intptr_t));
    if (argc > 0) { memcpy(vcStk->p, argv, argc * sizeof (intptr_t)); vcStk->n = argc1 * sizeof (intptr_t); }
    intptr_t *lab, pc, *reg = NULL, *subArg = NULL, *arg = (intptr_t *) vcStk->p, retVal = 0, argIdx = 0;
    double *frg = NULL;
    a_A4vm_exec0_funcInfo *inf;
    for (pc = 0; pc < bn; pc += 4) {
        if (bp[pc] == 0x03) {
            a_VecChr_reserve(vcLbl, (bp[pc + 1] + 1) * sizeof (intptr_t));
            lab = (intptr_t *) vcLbl->p;
            lab[bp[pc + 1]] = pc + 4;  // Lbl_T(t)命令の次の命令を指す.
        }
    }
    for (pc = 0;;) {
        intptr_t op = bp[pc], a = bp[pc + 1], b = bp[pc + 2], c = bp[pc + 3], d; pc += 4;
        switch (op) {
        case 0x00: continue;
        case 0x01: pc = lab[a]; continue;
        case 0x02: retVal = a; goto err;
        case 0x03: continue;
        case 0x04: reg[a] = b; continue;
        case 0x05: reg[a] = reg[b]; continue;
        case 0x06: reg[a] = reg[b] |  c;      continue;
        case 0x07: reg[a] = reg[b] |  reg[c]; continue;
        case 0x08: reg[a] = reg[b] ^  c;      continue;
        case 0x09: reg[a] = reg[b] ^  reg[c]; continue;
        case 0x0a: reg[a] = reg[b] &  c;      continue;
        case 0x0b: reg[a] = reg[b] &  reg[c]; continue;
        case 0x0c: reg[a] = reg[b] << c;      continue;
        case 0x0d: reg[a] = reg[b] << reg[c]; continue;
        case 0x0e: reg[a] = reg[b] >> c;      continue;
        case 0x0f: reg[a] = reg[b] >> reg[c]; continue;
        case 0x10: reg[a] = reg[b] +  c;      continue;
        case 0x11: reg[a] = reg[b] +  reg[c]; continue;
        case 0x12: reg[a] = reg[b] -  c;      continue;
        case 0x13: reg[a] = reg[b] -  reg[c]; continue;
        case 0x14: reg[a] = reg[b] *  c;      continue;
        case 0x15: reg[a] = reg[b] *  reg[c]; continue;
        case 0x16: reg[a] = reg[b] /  c;      continue;
        case 0x17: reg[a] = reg[b] /  reg[c]; continue;
        case 0x18: reg[a] = reg[b] %  c;      continue;
        case 0x19: reg[a] = reg[b] %  reg[c]; continue;
        case 0x1a: reg[a] = c      -  reg[b]; continue;
        case 0x1b: reg[a] = c      /  reg[b]; continue;
        case 0x1c: reg[a] = c      %  reg[b]; continue;
        case 0x1d: d = bp[pc + 1]; pc += 4; reg[a] = (intptr_t)(((int64_t)reg[b]*(int64_t)reg[c])>>d); continue;
        case 0x1e: reg[a] = a_double2intptr(cos(reg[b] * (2 * 3.14159265358979323 / 65536)) * 65536); continue;
        case 0x1f: reg[a] = a_double2intptr(sin(reg[b] * (2 * 3.14159265358979323 / 65536)) * 65536); continue;
        case 0x20: reg[a] = (reg[b] <  c);      continue;
        case 0x21: reg[a] = (reg[b] <  reg[c]); continue;
        case 0x22: reg[a] = (reg[b] >= c);      continue;
        case 0x23: reg[a] = (reg[b] >= reg[c]); continue;
        case 0x24: reg[a] = (reg[b] <= c);      continue;
        case 0x25: reg[a] = (reg[b] <= reg[c]); continue;
        case 0x26: reg[a] = (reg[b] >  c);      continue;
        case 0x27: reg[a] = (reg[b] >  reg[c]); continue;
        case 0x28: reg[a] = (reg[b] == c);      continue;
        case 0x29: reg[a] = (reg[b] == reg[c]); continue;
        case 0x2a: reg[a] = (reg[b] != c);      continue;
        case 0x2b: reg[a] = (reg[b] != reg[c]); continue;
        case 0x2c: if (b >= 256) { reg[a] = arg[b - 256]; } else { reg[a] = subArg[b]; } continue; // Lod_RA
        case 0x2d: if (a >= 256) { arg[a - 256] = reg[b]; } else { subArg[a] = reg[b]; } continue; // Lod_AR
        case 0x2e: if (a >= 256) { arg[a - 256] = b;      } else { subArg[a] = b;      } continue; // Lod_AI
        case 0x2f: inf = (a_A4vm_exec0_funcInfo *) (vcInf->p + vcInf->n - sizeof (a_A4vm_exec0_funcInfo)); // call
            inf->pc = pc; inf->arg = argIdx; arg = subArg; argIdx = inf->subArg; pc = lab[a]; continue;
        case 0x30: if (reg[b] <  c)      { pc = lab[a]; } continue;
        case 0x31: if (reg[b] <  reg[c]) { pc = lab[a]; } continue;
        case 0x32: if (reg[b] >= c)      { pc = lab[a]; } continue;
        case 0x33: if (reg[b] >= reg[c]) { pc = lab[a]; } continue;
        case 0x34: if (reg[b] <= c)      { pc = lab[a]; } continue;
        case 0x35: if (reg[b] <= reg[c]) { pc = lab[a]; } continue;
        case 0x36: if (reg[b] >  c)      { pc = lab[a]; } continue;
        case 0x37: if (reg[b] >  reg[c]) { pc = lab[a]; } continue;
        case 0x38: if (reg[b] == c)      { pc = lab[a]; } continue;
        case 0x39: if (reg[b] == reg[c]) { pc = lab[a]; } continue;
        case 0x3a: if (reg[b] != c)      { pc = lab[a]; } continue;
        case 0x3b: if (reg[b] != reg[c]) { pc = lab[a]; } continue;
        case 0x3c: reg[a] = a_double2intptr(sqrt(reg[b] * (1.0 / 65536)) * 65536); continue;
        case 0x3d:
            if (b == 0) { intptr_t (*fn)() = (void *) a; reg[c] = fn(); continue; }
            if (b <= 3) { intptr_t (*fn)(intptr_t, intptr_t, intptr_t) = (void *) a; reg[c] = fn(reg[bp[pc+1]], reg[bp[pc+2]], reg[bp[pc+3]]); pc += 4; continue; }
            if (b <= 6) { intptr_t (*fn)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t) = (void *) a;
               reg[c] = fn(reg[bp[pc+1]], reg[bp[pc+2]], reg[bp[pc+3]], reg[bp[pc+5]], reg[bp[pc+6]], reg[bp[pc+7]]); pc += 8; continue; }
            if (b <= 9) { intptr_t (*fn)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t) = (void *) a;
               reg[c] = fn(reg[bp[pc+1]], reg[bp[pc+2]], reg[bp[pc+3]], reg[bp[pc+5]], reg[bp[pc+6]], reg[bp[pc+7]], reg[bp[pc+9]], reg[bp[pc+10]], reg[bp[pc+11]]); pc += 12; continue; }
        case 0x3e: // enter
            pc += 4; inf = a_VecChr_stkAdd(vcInf, sizeof (a_A4vm_exec0_funcInfo)); a = (a + 1) & -2; c = (c + 1) & -2;
            inf->prv = vcStk->n; a_VecChr_resizeDiff(_arg_ vcStk, (a + b * 2 + c) * sizeof (intptr_t));
            inf->reg = inf->prv; inf->frg = inf->reg + a * sizeof (intptr_t); inf->subArg = inf->frg + b * 2 * sizeof (intptr_t);
            reg = (intptr_t *) (vcStk->p + inf->reg); frg = (double *) (vcStk->p + inf->frg); subArg = (intptr_t *) (vcStk->p + inf->subArg);
            arg = (intptr_t *) (vcStk->p + argIdx); continue;
        case 0x3f: // leave/return
            inf = a_VecChr_stkRmv(vcInf, sizeof (a_A4vm_exec0_funcInfo));
            vcStk->n = inf->prv; if (vcInf->n == 0) goto fin;
            inf--; reg = (intptr_t *) (vcStk->p + inf->reg); frg = (double *) (vcStk->p + inf->frg); subArg = (intptr_t *) (vcStk->p + inf->subArg);
            argIdx = inf->arg; arg = (intptr_t *) (vcStk->p + argIdx); pc = inf->pc; continue;

        case 0x40: frg[a] = (double) *(float *) &bp[pc - 2]; continue;
        case 0x41: frg[a] = frg[b]; continue;
        case 0x42: frg[a] = (double) reg[b]; continue;
        case 0x43: reg[a] = (intptr_t) frg[b]; continue;
        case 0x44: frg[a] = *(double *) &bp[pc - 2]; continue;
        case 0x45: if (a >= 256) { *(double *) &arg[a - 256] = *(double *) &bp[pc - 2]; } else { *(double *) &subArg[a] = *(double *) &bp[pc - 2]; } continue;// lod_AJ
        case 0x46: frg[a] = (double) *(float *) &bp[pc - 1] - frg[b]; continue;
        case 0x47: frg[a] = (double) *(float *) &bp[pc - 1] / frg[b]; continue;
        case 0x48: frg[a] = frg[b] + (double) *(float *) &bp[pc - 1]; continue;
        case 0x49: frg[a] = frg[b] + frg[c];                          continue;
        case 0x4a: frg[a] = frg[b] - (double) *(float *) &bp[pc - 1]; continue;
        case 0x4b: frg[a] = frg[b] - frg[c];                          continue;
        case 0x4c: frg[a] = frg[b] * (double) *(float *) &bp[pc - 1]; continue;
        case 0x4d: frg[a] = frg[b] * frg[c];                          continue;
        case 0x4e: frg[a] = frg[b] / (double) *(float *) &bp[pc - 1]; continue;
        case 0x4f: frg[a] = frg[b] / frg[c];                          continue;
        case 0x50: frg[a] = fabs(frg[b]);  continue;
        case 0x51: frg[a] = sqrt(frg[b]);  continue;
        case 0x52: frg[a] = exp(frg[b]);   continue;
        case 0x53: frg[a] = log(frg[b]);   continue;
        case 0x54: frg[a] = cos(frg[b]);   continue;
        case 0x55: frg[a] = sin(frg[b]);   continue;
        case 0x56: frg[a] = tan(frg[b]);   continue;
        case 0x57: frg[a] = pow(frg[b]);   continue;
        case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d:
        case 0x5e: frg[a] = floor(frg[b]); continue;
        case 0x5f: frg[a] = ceil(frg[b]);  continue;
        case 0x60: reg[a] = (frg[b] <  (double) *(float *) &bp[pc - 1]); continue;
        case 0x61: reg[a] = (frg[b] <  frg[c]);                          continue;
        case 0x62: reg[a] = (frg[b] >= (double) *(float *) &bp[pc - 1]); continue;
        case 0x63: reg[a] = (frg[b] >= frg[c]);                          continue;
        case 0x64: reg[a] = (frg[b] <= (double) *(float *) &bp[pc - 1]); continue;
        case 0x65: reg[a] = (frg[b] <= frg[c]);                          continue;
        case 0x66: reg[a] = (frg[b] >  (double) *(float *) &bp[pc - 1]); continue;
        case 0x67: reg[a] = (frg[b] >  frg[c]);                          continue;
        case 0x68: reg[a] = (frg[b] == (double) *(float *) &bp[pc - 1]); continue;
        case 0x69: reg[a] = (frg[b] == frg[c]);                          continue;
        case 0x6a: reg[a] = (frg[b] != (double) *(float *) &bp[pc - 1]); continue;
        case 0x6b: reg[a] = (frg[b] != frg[c]);                          continue;
        case 0x6c: if (b >= 256) { frg[a] = *(double *) &arg[b - 256]; } else { frg[a] = *(double *) &subArg[b]; } continue; // Lod_FA
        case 0x6d: if (a >= 256) { *(double *) &arg[a - 256] = frg[b]; } else { *(double *) &subArg[a] = frg[b]; } continue; // Lod_AF
        case 0x6e:
        case 0x6f:
        case 0x70: if (frg[b] <  (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x71: if (frg[b] <  frg[c])                          { pc = lab[a]; } continue;
        case 0x72: if (frg[b] >= (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x73: if (frg[b] >= frg[c])                          { pc = lab[a]; } continue;
        case 0x74: if (frg[b] <= (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x75: if (frg[b] <= frg[c])                          { pc = lab[a]; } continue;
        case 0x76: if (frg[b] >  (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x77: if (frg[b] >  frg[c])                          { pc = lab[a]; } continue;
        case 0x78: if (frg[b] == (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x79: if (frg[b] == frg[c])                          { pc = lab[a]; } continue;
        case 0x7a: if (frg[b] != (double) *(float *) &bp[pc - 1]) { pc = lab[a]; } continue;
        case 0x7b: if (frg[b] != frg[c])                          { pc = lab[a]; } continue;
        case 0x7c:
        case 0x7d:
        case 0x7e:
        case 0x7f:
            ;
        }
    }
fin:
    retVal = arg[0];
    memcpy(argv, vcStk->p, argc * sizeof (intptr_t));
err:
    a_VecChr_din4(vcLbl, vcInf, vcStk, 0);
    return retVal;
}

(3) a4vm-asm-v0.h

#define Nop()               0x0000, 0, 0, 0
#define Jmp_T(t)            0x0001, t, 0, 0
#define Abt_I(i)            0x0002, i, 0, 0
#define Lbl_T(t)            0x0003, t, 0, 0
#define Lod_RI(r, i)        0x0004, r, i, 0
#define Lod_RR(r, s)        0x0005, r, s, 0
#define Or__RRI(r, s, i)    0x0006, r, s, i
#define Or__RRR(r, s, t)    0x0007, r, s, t
#define Xor_RRI(r, s, i)    0x0008, r, s, i
#define Xor_RRR(r, s, t)    0x0009, r, s, t
#define And_RRI(r, s, i)    0x000a, r, s, i
#define And_RRR(r, s, t)    0x000b, r, s, t
#define Shl_RRI(r, s, i)    0x000c, r, s, i
#define Shl_RRR(r, s, t)    0x000d, r, s, t
#define Shr_RRI(r, s, i)    0x000e, r, s, i
#define Shr_RRR(r, s, t)    0x000f, r, s, t
#define Add_RRI(r, s, i)    0x0010, r, s, i
#define Add_RRR(r, s, t)    0x0011, r, s, t
#define Sub_RRI(r, s, i)    0x0012, r, s, i
#define Sub_RRR(r, s, t)    0x0013, r, s, t
#define Mul_RRI(r, s, i)    0x0014, r, s, i
#define Mul_RRR(r, s, t)    0x0015, r, s, t
#define Div_RRI(r, s, i)    0x0016, r, s, i
#define Div_RRR(r, s, t)    0x0017, r, s, t
#define Mod_RRI(r, s, i)    0x0018, r, s, i
#define Mod_RRR(r, s, t)    0x0019, r, s, t
#define Sub_RIR(r, i, s)    0x001a, r, s, i
#define Div_RIR(r, i, s)    0x001b, r, s, i
#define Mod_RIR(r, i, s)    0x001c, r, s, i
#define Mul64Shr_RRRI(r, s, t, i)   0x001d, r, s, t, 0x2, i, 0, 0
#define Cos16_RR(r, s)      0x001e, r, s, 0
#define Sin16_RR(r, s)      0x001f, r, s, 0
#define Clt_RRI(r, s, i)    0x0020, r, s, i
#define Clt_RRR(r, s, t)    0x0021, r, s, t
#define Cge_RRI(r, s, i)    0x0022, r, s, i
#define Cge_RRR(r, s, t)    0x0023, r, s, t
#define Cle_RRI(r, s, i)    0x0024, r, s, i
#define Cle_RRR(r, s, t)    0x0025, r, s, t
#define Cgt_RRI(r, s, i)    0x0026, r, s, i
#define Cgt_RRR(r, s, t)    0x0027, r, s, t
#define Ceq_RRI(r, s, i)    0x0028, r, s, i
#define Ceq_RRR(r, s, t)    0x0029, r, s, t
#define Cne_RRI(r, s, i)    0x002a, r, s, i
#define Cne_RRR(r, s, t)    0x002b, r, s, t
#define Lod_RA(r, a)        0x002c, r, a, 0
#define Lod_AR(a, r)        0x002d, a, r, 0
#define Lod_AI(a, i)        0x002e, a, i, 0
#define Cal_T(t)            0x002f, t, 0, 0
#define Jlt_RIT(r, i, t)    0x0030, t, r, i
#define Jlt_RRT(r, s, t)    0x0031, t, r, s
#define Jge_RIT(r, i, t)    0x0032, t, r, i
#define Jge_RRT(r, s, t)    0x0033, t, r, s
#define Jle_RIT(r, i, t)    0x0034, t, r, i
#define Jle_RRT(r, s, t)    0x0035, t, r, s
#define Jgt_RIT(r, i, t)    0x0036, t, r, i
#define Jgt_RRT(r, s, t)    0x0037, t, r, s
#define Jeq_RIT(r, i, t)    0x0038, t, r, i
#define Jeq_RRT(r, s, t)    0x0039, t, r, s
#define Jne_RIT(r, i, t)    0x003a, t, r, i
#define Jne_RRT(r, s, t)    0x003b, t, r, s
#define Sqr16_RR(r, s)      0x003c, r, s, 0
// 003d
#define Ent_III(i, j, k)    0x003e, i, j, k, 0x2, 0, 0, 0
#define Lev_III(i, j, k)    0x003f, i, j, k, 0x2, 0, 0, 0

#define Lod_FI(f, i)        0x0040, f, i, 0
#define Lod_FF(f, g)        0x0041, f, g, 0
#define Lod_FR(f, r)        0x0042, f, r, 0
#define Lod_RF(r, f)        0x0043, r, f, 0
#define Lod_FJ(f, j, k)     0x0044, f, j, k
#define Lod_AJ(a, j, k)     0x0045, a, j, k
#define Sub_FIF(f, i, g)    0x0046, f, g, i
#define Div_FIF(f, i, g)    0x0047, f, g, i
#define Add_FFI(f, g, i)    0x0048, f, g, i
#define Add_FFF(f, g, h)    0x0049, f, g, h
#define Sub_FFI(f, g, i)    0x004a, f, g, i
#define Sub_FFF(f, g, h)    0x004b, f, g, h
#define Mul_FFI(f, g, i)    0x004c, f, g, i
#define Mul_FFF(f, g, h)    0x004d, f, g, h
#define Div_FFI(f, g, i)    0x004e, f, g, i
#define Div_FFF(f, g, h)    0x004f, f, g, h
#define Abs_FF(f, g)        0x0050, f, g, 0
#define Sqr_FF(f, g)        0x0051, f, g, 0
#define Exp_FF(f, g)        0x0052, f, g, 0
#define Log_FF(f, g)        0x0053, f, g, 0
#define Cos_FF(f, g)        0x0054, f, g, 0
#define Sin_FF(f, g)        0x0055, f, g, 0
#define Tan_FF(f, g)        0x0056, f, g, 0
#define Pow_FF(f, g)        0x0057, f, g, 0
// 0058-005d
#define Flr_FF(f, g)        0x005e, f, g, 0
#define Cel_FF(f, g)        0x005f, f, g, 0
#define Clt_RFI(r, f, i)    0x0060, r, f, i
#define Clt_RFF(r, f, g)    0x0061, r, f, g
#define Cge_RFI(r, f, i)    0x0062, r, f, i
#define Cge_RFF(r, f, g)    0x0063, r, f, g
#define Cle_RFI(r, f, i)    0x0064, r, f, i
#define Cle_RFF(r, f, g)    0x0065, r, f, g
#define Cgt_RFI(r, f, i)    0x0066, r, f, i
#define Cgt_RFF(r, f, g)    0x0067, r, f, g
#define Ceq_RFI(r, f, i)    0x0068, r, f, i
#define Ceq_RFF(r, f, g)    0x0069, r, f, g
#define Cne_RFI(r, f, i)    0x006a, r, f, i
#define Cne_RFF(r, f, g)    0x006b, r, f, g
#define Lod_FA(f, a)        0x006c, f, a, 0
#define Lod_AF(a, f)        0x006d, a, f, 0
// 006e-006f
#define Jlt_FIT(f, i, t)    0x0070, t, f, i
#define Jlt_FFT(f, g, t)    0x0071, t, f, g
#define Jge_FIT(f, i, t)    0x0072, t, f, i
#define Jge_FFT(f, g, t)    0x0073, t, f, g
#define Jle_FIT(f, i, t)    0x0074, t, f, i
#define Jle_FFT(f, g, t)    0x0075, t, f, g
#define Jgt_FIT(f, i, t)    0x0076, t, f, i
#define Jgt_FFT(f, g, t)    0x0077, t, f, g
#define Jeq_FIT(f, i, t)    0x0078, t, f, i
#define Jeq_FFT(f, g, t)    0x0079, t, f, g
#define Jne_FIT(f, i, t)    0x007a, t, f, i
#define Jne_FFT(f, g, t)    0x007b, t, f, g
// 007c-007f

(4) サンプルプログラム: t0014a.c


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS