📄 intr386.c
字号:
gen_pop(EDI, am_dreg, 0);
if (ap1 == 0)
ap1 = clreg;
return ap1;
}
//-------------------------------------------------------------------------
static AMODE *popSIDI(AMODE *ap, int tocx)
{
AMODE *ap1 = popDI(ap, tocx);
gen_pop(ESI, am_dreg, 0);
return ap1;
}
//-------------------------------------------------------------------------
static void skipdi(void)
{
gen_code(op_sub, makedreg(EAX), makedreg(EAX));
gen_code(op_mov, makedreg(ECX), make_immed( - 1));
gen_code(op_repnz, 0, 0);
gen_code(op_scasb, 0, 0);
gen_code(op_dec, makedreg(EDI), 0);
}
//-------------------------------------------------------------------------
static AMODE *xstrlen(int todec)
{
AMODE *ap1;
gen_code(op_sub, makedreg(EAX), makedreg(EAX));
gen_code(op_mov, makedreg(ECX), make_immed( - 1));
gen_code(op_repnz, 0, 0);
gen_code(op_scasb, 0, 0);
gen_code(op_not, makedreg(ECX), 0);
if (todec)
gen_code(op_dec, makedreg(ECX), 0);
ap1 = temp_data();
if (ap1->preg != ECX)
gen_code(op_mov, ap1, makedreg(ECX));
return ap1;
}
//-------------------------------------------------------------------------
static void xmove(void)
{
gen_code3(op_shrd, makedreg(EAX), makedreg(ECX), make_immed(2));
gen_code(op_shr, makedreg(ECX), make_immed(2));
gen_code(op_repnz, 0, 0);
gen_code(op_movsd, 0, 0);
gen_code3(op_shld, makedreg(ECX), makedreg(EAX), make_immed(2));
gen_code(op_repnz, 0, 0);
gen_code(op_movsb, 0, 0);
}
//-------------------------------------------------------------------------
static void xset(void)
{
gen_codes(op_mov, 1, makedreg(4), makedreg(0));
gen_code2(op_movzx, 4, 2, makedreg(EDX), makedreg(EAX));
gen_code(op_shl, makedreg(EAX), make_immed(16));
gen_code(op_or, makedreg(EAX), makedreg(EDX));
gen_code3(op_shrd, makedreg(EDX), makedreg(ECX), make_immed(2));
gen_code(op_shr, makedreg(ECX), make_immed(2));
gen_code(op_repnz, 0, 0);
gen_code(op_stosd, 0, 0);
gen_code3(op_shld, makedreg(ECX), makedreg(EDX), make_immed(2));
gen_code(op_repnz, 0, 0);
gen_code(op_stosb, 0, 0);
}
//-------------------------------------------------------------------------
static AMODE *xstrcmp(void)
{
int neg = nextlabel++, exit = nextlabel++;
AMODE *ap1 = temp_data();
gen_code(op_repz, 0, 0);
gen_code(op_cmpsb, 0, 0);
gen_code(op_mov, ap1, make_immed(0));
gen_code(op_je, make_label(exit), 0);
gen_code(op_js, make_label(neg), 0);
gen_code(op_inc, ap1, 0);
gen_comment("; TEST EAX,IMMED (branches around next four bytes of code)\n");
gen_codes(op_genword, 0, make_immed(0xa9), 0);
gen_codes(op_nop, 0, 0, 0);
gen_codes(op_nop, 0, 0, 0);
gen_codes(op_nop, 0, 0, 0);
gen_label(neg);
gen_code(op_dec, ap1, 0);
gen_label(exit);
return ap1;
}
//-------------------------------------------------------------------------
AMODE *inport(ENODE *parms, int size)
{
AMODE *ap1;
int pushed = FALSE, pushedax = FALSE;
if (!oneparm(parms))
return 0;
ap1 = gen_expr(parms->v.p[0], 0, 0, 2);
if (ap1->mode != am_dreg || ap1->preg != EDX)
{
freeop(ap1);
if (regs[2])
{
pushed = TRUE;
gen_push(EDX, am_dreg, 0);
}
gen_codes(op_mov, 2, makedreg(EDX), ap1);
}
if (regs[0])
{
pushedax = TRUE;
gen_push(EAX, am_dreg, 0);
}
switch (size)
{
case 1:
gen_code(op_in, alreg, dxreg);
gen_code(op_movzx, makedreg(EAX), alreg);
break;
case 2:
gen_code(op_in, axreg, dxreg);
gen_code(op_movzx, makedreg(EAX), axreg);
break;
}
if (pushedax)
{
ap1 = temp_data();
gen_code(op_mov, ap1, makedreg(EAX));
gen_pop(EAX, am_dreg, 0);
}
else
{
regs[0]++;
ap1 = makedreg(EAX);
}
if (pushed)
gen_pop(EDX, am_dreg, 0);
return ap1;
}
//-------------------------------------------------------------------------
AMODE *outport(ENODE *parms, int size)
{
AMODE *ap1, *ap2;
int pushed = FALSE, pushedax = FALSE;
if (!twoparms(parms))
return 0;
ap2 = gen_expr(parms->v.p[0], FALSE, FALSE, size);
if (regs[0] && (ap2->mode != am_dreg || ap2->preg != EAX))
{
pushedax = TRUE;
gen_push(EAX, am_dreg, 0);
regs[0]--;
}
else
do_extend(ap2, size, F_DREG | F_VOL);
ap1 = gen_expr(parms->v.p[1]->v.p[0], FALSE, FALSE, 2);
if (ap1->mode != am_dreg || ap1->preg != EDX)
{
freeop(ap1);
if (regs[2])
{
pushed = TRUE;
gen_push(EDX, am_dreg, 0);
}
gen_codes(op_mov, 2, makedreg(EDX), ap1);
}
switch (size)
{
case 1:
gen_code(op_out, dxreg, alreg);
break;
case 2:
gen_code(op_out, dxreg, axreg);
break;
}
if (pushed)
gen_pop(EDX, am_dreg, 0);
if (pushedax)
{
gen_pop(EAX, am_dreg, 0);
regs[0]++;
}
return ap1;
}
//-------------------------------------------------------------------------
AMODE *HandleIntrins(ENODE *node, int novalue)
{
ENODE *parms = node->v.p[1]->v.p[1]->v.p[0];
AMODE *ap1, *ap2, *ap3;
SYM *sp;
int xchg = FALSE;
if (prm_intrinsic && (node->v.p[1]->v.p[0]->nodetype == en_nacon || node
->v.p[1]->v.p[0]->nodetype == en_napccon) && ((sp = node->v.p[1]
->v.p[0]->v.sp)->tp->cflags &DF_INTRINS))
{
switch (sp->value.i)
{
case 1:
/* abs */
if (!oneparm(parms))
return 0;
ap1 = gen_expr(parms->v.p[0], 0, 0, 4);
do_extend(ap1, ap1->length, F_DREG | F_VOL);
if (ap1->preg != EAX)
{
gen_code(op_xchg, ap1, makedreg(EAX));
xchg = TRUE;
}
if (regs[2])
gen_push(EDX, am_dreg, 0);
gen_code(op_cdq, 0, 0);
gen_code(op_xor, makedreg(EAX), edxreg);
gen_code(op_sub, makedreg(EAX), edxreg);
if (regs[2])
gen_pop(EDX, am_dreg, 0);
if (xchg)
gen_code(op_xchg, ap1, makedreg(EAX));
return ap1;
case 2:
/* div */
case 3:
/* ldiv */
break;
case 4:
/* _rotl */
return roll(parms, 4, op_rol);
case 5:
/* _rotr */
return roll(parms, 4, op_ror);
case 6:
/* memcmp */
if (!threeparms(parms))
return 0;
gen_push(ESI, am_dreg, 0);
gen_push(EDI, am_dreg, 0);
LoadCX(parms->v.p[0]);
LoadSIDI(parms->v.p[1], TRUE, FALSE);
ap1 = xstrcmp();
return popSIDI(ap1, 0);
case 7:
/* memcpy */
if (!threeparms(parms))
return 0;
gen_push(ESI, am_dreg, 0);
gen_push(EDI, am_dreg, 0);
LoadCX(parms->v.p[0]);
LoadSIDI(parms->v.p[1], FALSE, FALSE);
xmove();
return popSIDI(0, 0);
case 8:
/* memmove */
break;
case 9:
/* memset */
if (!threeparms(parms))
return 0;
gen_push(EDI, am_dreg, 0);
LoadDI(parms->v.p[1]->v.p[1], FALSE);
ap2 = gen_expr(parms->v.p[1]->v.p[0], FALSE, FALSE, 4);
do_extend(ap2, 4, F_DREG | F_VOL);
if (ap2->preg != EAX)
gen_code(op_mov, makedreg(EAX), ap2);
regs[0]++;
ap1 = gen_expr(parms->v.p[0], FALSE, FALSE, 4);
do_extend(ap1, 4, F_DREG | F_VOL);
if (ap1->preg != ECX)
gen_code(op_mov, makedreg(ECX), ap1);
regs[0]--;
freeop(ap1);
freeop(ap2);
xset();
return popDI(0, 0);
case 10:
/* strcat */
if (!twoparms(parms))
return 0;
gen_push(ESI, am_dreg, 0);
gen_push(EDI, am_dreg, 0);
LoadSIDI(parms, FALSE, TRUE);
skipdi();
gen_code(op_xchg, makedreg(ESI), makedreg(EDI));
gen_push(EDI, am_dreg, 0);
xstrlen(FALSE);
gen_pop(EDI, am_dreg, 0);
gen_code(op_xchg, makedreg(ESI), makedreg(EDI));
xmove();
popSIDI(0, 0);
ap1 = gen_expr(parms->v.p[1]->v.p[0], FALSE, FALSE, 0);
return ap1;
case 11:
/* strcmp */
if (!twoparms(parms))
return 0;
gen_push(ESI, am_dreg, 0);
gen_push(EDI, am_dreg, 0);
LoadSIDI(parms, TRUE, TRUE);
gen_push(EDI, am_dreg, 0);
xstrlen(FALSE);
gen_pop(EDI, am_dreg, 0);
ap1 = xstrcmp();
return popSIDI(ap1, FALSE);
case 12:
/* strcpy */
if (!twoparms(parms))
return 0;
gen_push(ESI, am_dreg, 0);
gen_push(EDI, am_dreg, 0);
LoadSIDI(parms, TRUE, TRUE);
gen_push(EDI, am_dreg, 0);
xstrlen(FALSE);
gen_pop(EDI, am_dreg, 0);
gen_code(op_xchg, makedreg(ESI), makedreg(EDI));
xmove();
popSIDI(0, 0);
ap1 = gen_expr(parms->v.p[1]->v.p[0], FALSE, FALSE, 0);
return ap1;
case 13:
/* strlen */
if (!oneparm(parms))
return 0;
gen_push(EDI, am_dreg, 0);
LoadDI(parms, FALSE);
ap1 = xstrlen(TRUE);
return popDI(ap1, TRUE);
case 14:
/* strncat */
case 15:
/* strncmp */
case 16:
/* strncpy */
case 17:
/* memchr */
case 18:
/* strchr */
case 19:
/* strrchr */
break;
case 20:
/* inportb */
return inport(parms, 1);
case 21:
/* inport */
return inport(parms, 2);
case 22:
/* inp */
return inport(parms, 1);
case 23:
/* inpw */
return inport(parms, 2);
case 24:
/* outportb */
return outport(parms, 1);
case 25:
/* outport */
return outport(parms, 2);
case 26:
/* outp */
return outport(parms, 1);
case 27:
/* outpw */
return outport(parms, 2);
case 28:
/* _crotl */
return roll(parms, 1, op_rol);
case 29:
/* _crotr */
return roll(parms, 1, op_ror);
case 30:
/* _disable */
if (parms)
return 0;
gen_code(op_cli, 0, 0);
return 1;
case 31:
/* __enable */
if (parms)
return 0;
gen_code(op_sti, 0, 0);
return 1;
case 32:
/* inportd */
return inport(parms, 4);
case 33:
/* outportd */
return outport(parms, 4);
}
}
if (node->v.p[1]->v.p[0]->nodetype == en_nacon || node->v.p[1]->v.p[0]
->nodetype == en_napccon)
node->v.p[1]->v.p[0]->v.sp->tp->cflags &= ~DF_INTRINS;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -