?? oxccb.c
字號:
if(dsize <= ssize)
return;
if(ssize == 1)
obuf[1] |= SRC(UBYTE);
else if(ssize == 2)
obuf[1] |= SRC(USHORT);
else if(ssize == 4)
obuf[1] |= SRC(ULONG);
else if(ssize == 8)
obuf[1] |= SRC(CULONGLONG);
break;
}
default:
PERROR(pName ":ERROR: Line:%d bad conversion2\n", iv->lastline);
}
break;
}
case D_FLOAT: /* dest is float, double, long double */
{
if(dsize == 4)
obuf[1] = FLOAT;
else if(dsize == 8)
obuf[1] = DOUBLE;
else
obuf[1] = CLONGDOUBLE;
switch(sdtype)
{
case D_SIGNED:
{/* src is signed integer */
if(ssize == 1)
obuf[1] |= SRC(BYTE);
else if(ssize == 2)
obuf[1] |= SRC(SHORT);
else if(ssize == 4)
obuf[1] |= SRC(LONG);
else if(ssize == 8)
obuf[1] |= SRC(CLONGLONG);
break;
}
case D_UNSIGNED:
case D_SEGMENT:
{/* src is unsigned integer */
if(ssize == 1)
obuf[1] |= SRC(UBYTE);
else if(ssize == 2)
obuf[1] |= SRC(USHORT);
else if(ssize == 4)
obuf[1] |= SRC(ULONG);
else if(ssize == 8)
obuf[1] |= SRC(CULONGLONG);
break;
}
case D_FLOAT:
{/* src is floating point */
if(dsize == ssize)
return;
if(ssize == 4)
obuf[1] |= SRC(FLOAT);
else if(ssize == 8)
obuf[1] |= SRC(DOUBLE);
else
obuf[1] |= SRC(CLONGDOUBLE);
break;
}
case D_POINTER:
case D_FUNCPTR:
{/* src is unsigned integer */
if(ssize == 1)
obuf[1] |= SRC(UBYTE);
else if(ssize == 2)
obuf[1] |= SRC(USHORT);
else if(ssize == 4)
obuf[1] |= SRC(ULONG);
else if(ssize == 8)
obuf[1] |= SRC(CULONGLONG);
break;
}
default:
PERROR(pName ":ERROR: Line:%d bad conversion3\n", iv->lastline);
}
break;
}
case D_POINTER:
case D_FUNCPTR:
{/* dest is unsigned integer */
if(dsize == 1)
obuf[1] = BYTE;
else if(dsize == 2)
obuf[1] = SHORT;
else if(dsize == 4)
obuf[1] = LONG;
else if(dsize == 8)
obuf[1] = CLONGLONG;
switch(sdtype)
{
case D_SIGNED:
{/* src is signed integer */
if(dsize <= ssize)
return;
if(ssize == 1)
obuf[1] |= SRC(BYTE);
else if(ssize == 2)
obuf[1] |= SRC(SHORT);
else if(ssize == 4)
obuf[1] |= SRC(LONG);
else if(ssize == 8)
obuf[1] |= SRC(CLONGLONG);
break;
}
case D_UNSIGNED:
case D_SEGMENT:
{/* src is unsigned integer */
if(dsize <= ssize)
return;
if(ssize == 1)
obuf[1] |= SRC(UBYTE);
else if(ssize == 2)
obuf[1] |= SRC(USHORT);
else if(ssize == 4)
obuf[1] |= SRC(ULONG);
else if(ssize == 8)
obuf[1] |= SRC(CULONGLONG);
break;
}
case D_FLOAT:
{/* src is floating point */
if(ssize == 4)
obuf[1] |= SRC(FLOAT);
else if(ssize == 8)
obuf[1] |= SRC(DOUBLE);
else
obuf[1] |= SRC(CLONGDOUBLE);
break;
}
case D_POINTER:
case D_FUNCPTR:
{/* src is unsigned integer */
if(dsize <= ssize)
return;
if(ssize == 1)
obuf[1] |= SRC(UBYTE);
else if(ssize == 2)
obuf[1] |= SRC(USHORT);
else if(ssize == 4)
obuf[1] |= SRC(ULONG);
else if(ssize == 8)
obuf[1] |= SRC(CULONGLONG);
break;
}
default:
PERROR(pName ":ERROR: Line:%d bad conversion4\n", iv->lastline);
}
break;
}
default:
PRINTF("Line:%d no conversion\n", iv->lastline);
return;
}
write_obuf(iv, obuf, 2);
#undef SRC
}
static int
check_assignment_conversion(PND dst, PND src)
{
long dsize = dst->size;
long ssize = src->size;
unsigned char ddtype = dst->dtype;
unsigned char sdtype = src->dtype;
int ret = 0;
if(src->atype & (A_ABSOLUTE|A_POINTER|A_VALUE) == (A_POINTER|A_VALUE))
return 1;
switch(ddtype)
{
case D_SIGNED: /* dest is signed integer */
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
case D_FLOAT:
{
ret = 1;
break;
}
}
break;
}
case D_UNSIGNED: /* dest is unsigned integer */
case D_SEGMENT:
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
case D_FLOAT:
{
ret = 1;
break;
}
}
break;
}
case D_FLOAT: /* dest is float, double, long double */
{
if(sdtype == D_FLOAT)
{
if(dsize != ssize)
ret = 1;
}
else ret = 1;
break;
}
case D_POINTER:
case D_FUNCPTR: /* dest is pointer */
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
case D_FLOAT:
{
ret = 1;
break;
}
}
break;
}
}
return ret;
}
static int
check_binop_conversion(PND dst, PND src)
{
long dsize = dst->size;
long ssize = src->size;
unsigned char ddtype = dst->dtype;
unsigned char sdtype = src->dtype;
int ret = 0;
switch(ddtype)
{
case D_SIGNED: /* dest is signed integer */
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
}
break;
}
case D_UNSIGNED: /* dest is unsigned integer */
case D_SEGMENT:
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
}
break;
}
case D_FLOAT: /* dest is float, double, long double */
{
if(sdtype == D_FLOAT)
{
if(dsize > ssize)
ret = 1;
}
else ret = 1;
break;
}
case D_POINTER:
case D_FUNCPTR: /* dest is pointer */
{
switch(sdtype)
{
case D_SIGNED:
case D_UNSIGNED:
case D_SEGMENT:
case D_POINTER:
case D_FUNCPTR:
{
if(dsize > ssize)
ret = 1;
break;
}
}
break;
}
}
return ret;
}
static int
get_size(int type, int size)
{
switch(type)
{
case D_ARRAY:
case D_STRUCT:
case D_FUNCTION:
return B4;
default:
switch(size)
{
case 1:
return B1;
case 2:
return B2;
case 4:
return B4;
case 8:
return B8;
default:
#if SUPPORT_LONG_DOUBLE
return BX;
#endif
}
}
return 0;
}
static int
load_addr(Piv iv, unsigned char *poc, void *buf, PND pnd, int shft)
{/* Use the shortest possible representation */
long offset = pnd->OFFSET;
long ofs = offset >> 2;
if(pnd->atype & (A_EXTERN|A_ABSOLUTE))
{/* 4 bytes for absolute values */
*poc |= 3<<shft;
*((long*)buf) = offset;
iv->extmark += 1;
iv->markedsym[iv->extmark] = pnd->SYMNUM;
iv->markedbuf[iv->extmark] = buf;
return 4;
}
if(offset & 0xff000000)
{/* Relative values are restricted to 28 bits max */
PERROR(pName ":ERROR: Line:%d offset too large %x\n", iv->lastline, ofs);
return 0;
}
if(offset & 0xffff0000 || offset & 0x00000003)
{/* 3 bytes for large values and non-aligned values */
*poc |= 2<<shft;
*((long*)buf) = offset;
return 3;
}
else if(ofs & 0xffffff00)
{/* 2 or fewer bytes for small aligned values */
*poc |= 1<<shft;
*((short*)buf) = (short)ofs;
return 2;
}
else
{
*((char*)buf) = (char)ofs;
return 1;
}
}
static void
load_val(Piv iv, unsigned long val)
{
unsigned char obuf[10];
obuf[0] = LUI;
++iv->stackdepth;
if(val & 0xffff0000)
{
obuf[0] |= 2;
*((unsigned long*)&obuf[1]) = val;
write_obuf(iv, obuf, 5);
}
else if(val & 0xffffff00)
{
obuf[0] |= 1;
*((unsigned short*)&obuf[1]) = (unsigned short)val;
write_obuf(iv, obuf, 3);
}
else
{
obuf[1] = (unsigned char)val;
write_obuf(iv, obuf, 2);
}
}
static int
load_immed(Piv iv, unsigned char *poc, void *obuf, PND pnd, int osize)
{
unsigned short dtype = pnd->dtype;
unsigned char mosize = pnd->opsize;
void *ibuf = pnd->data;
if(osize >= 0)
{/* force the immediate value to conform to osize */
if(osize == mosize)
{
switch(osize)
{
case B1:
*((char*)obuf) = *((char*)ibuf);
return 1;
case B2:
*((short*)obuf) = *((short*)ibuf);
return 2;
case B4:
*((long*)obuf) = *((long*)ibuf);
return 4;
case B8:
*((double*)obuf) = *((double*)ibuf);
return 8;
case BX:
#if SUPPORT_LONG_DOUBLE
*((long double*)obuf) = *((long double*)ibuf);
#else
memcpy(obuf, ibuf, XSZ);
#endif
return XSZ;
default:
PERROR(pName ":ERROR: Line:%d LOAD IMMED SYSERR osize=%d\n", iv->lastline, osize);
}
}
else /* osize != mosize */
{
if(dtype == D_FLOAT)
{
float f;
double d;
#if SUPPORT_LONG_DOUBLE
long double ld;
#endif
switch(osize)
{
case B4:
switch(mosize)
{
case B8:
f = (float)*((double*)ibuf);
*((float*)obuf) = f;
return 4;
case BX:
#if SUPPORT_LONG_DOUBLE
f = (float)*((long double*)ibuf);
*((float*)obuf) = f;
return 4;
#else
PERROR(pName ":ERROR: Line:%d long double conversion not supported\n", iv->lastline);
#endif
default:
PERROR(pName ":ERROR: Line:%d bad floating immediate input\n",iv->lastline);
}
case B8:
switch(mosize)
{
case B4:
d = (double)*((float*)ibuf);
*((double*)obuf) = d;
return 8;
case BX:
#if SUPPORT_LONG_DOUBLE
d = (double)*((long double*)ibuf);
*((double*)obuf) = d;
return 8;
#else
PERROR(pName ":ERROR: Line:%d long double conversion not supported\n", iv->lastline);
#endif
default:
PERROR(pName ":ERROR: Line:%d bad floating immediate input\n", iv->lastline);
}
case BX:
#if SUPPORT_LONG_DOUBLE
switch(mosize)
{
case B4:
ld = (long double)*((float*)ibuf);
*((long double*)obuf) = ld;
return XSZ;
case B8:
ld = (long double)*((double*)ibuf);
*((long double*)obuf) = ld;
return XSZ;
default:
PERROR(pName ":ERROR: Line:%d bad floating immediate input\n", iv->lastline);
}
break;
#else
PERROR(pName ":ERROR: Line:%d long double conversion not supported\n", iv->lastline);
#endif
break;
default:
PERROR(pName ":ERROR: Line:%d bad floating immediate output\n", iv->lastline);
}
}/* END: dtype == D_FLOAT */
else if(dtype == D_UNSIGNED || dtype == D_POINTER)
{
switch(osize)
{
case B1:
*((unsigned char*)obuf) = *((unsigned char *)ibuf);
return 1;
case B2:
switch(mosize)
{
case B1:
*((unsigned short*)obuf) = *((unsigned char*)ibuf);
return 2;
case B4:
case B8:
*((unsigned short*)obuf) = *((unsigned short*)ibuf);
return 2;
case BX:
PERROR(pName ":ERROR: Line:%d invalid integer size\n", iv->lastline);
default:
PERROR(pName ":ERROR: Line:%d invalid immediate input\n", iv->lastline);
}
case B4:
switch(mosize)
{
case B1:
*((unsigned long*)obuf) = *((unsigned char*)ibuf);
return 4;
case B2:
*((unsigned long*)obuf) = *((unsigned short*)ibuf);
return 4;
case B8:
*((unsigned long*)obuf) = *((unsigned long*)ibuf);
return 4;
case BX:
PERROR(pName ":ERROR: Line: invalid integer size\n", iv->lastline);
default:
PERROR(pName ":ERROR: Line:%d invalid immediate input\n", iv->lastline);
}
case B8:
{
unsigned long l[2];
l[0] = 0;
l[1] = 0;
if(mosize == B4)
l[0] = *((unsigned long*)ibuf);
else if(mosize == B2)
l[0] = *((unsigned short*)ibuf);
else if(mosize == B1)
l[0] = *((unsigned char*)ibuf);
else
PERROR(pName ":ERROR: Line:%d invalid integer size\n", iv->lastline);
memcpy(obuf, l, 8);
return 8;
}
default:
PERROR(pName ":ERROR: Line:%d invalid integer size=%d\n",
iv->lastline, osize);
}
}
else /* signed integer */
{
switch(osize)
{
case B1:
*((char*)obuf) = *((char *)ibuf);
return 1;
case B2:
switch(mosize)
{
case B1:
*((short*)obuf) = *((char*)ibuf);
return 2;
case B4:
case B8:
*((short*)obuf) = *((short*)ibuf);
return 2;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -