250 lines
3.8 KiB
C
250 lines
3.8 KiB
C
|
branch(brtyp, link, val)
|
||
|
word_t brtyp;
|
||
|
word_t link;
|
||
|
valu_t val;
|
||
|
{
|
||
|
valu_t offset;
|
||
|
|
||
|
offset = val - DOTVAL - 8;
|
||
|
if ((offset & 0xFC000000) != 0 && (offset & 0xFC000000) != 0xFC000000){
|
||
|
serror("offset out of range");
|
||
|
}
|
||
|
offset = offset>>2 & 0xFFFFFF;
|
||
|
emit4(brtyp|link|offset);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
data(opc, ins, val, typ)
|
||
|
word_t opc, ins;
|
||
|
valu_t val;
|
||
|
short typ;
|
||
|
{
|
||
|
valu_t tmpval;
|
||
|
|
||
|
if (typ == S_REG){
|
||
|
emit4(opc|ins|val);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ins |= 0x02000000;
|
||
|
|
||
|
tmpval = val;
|
||
|
if (typ == S_ABS){
|
||
|
if (calcimm(&opc, &tmpval, typ)){
|
||
|
emit4(opc|ins|tmpval);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
tmpval = val;
|
||
|
if (small(calcimm(&opc, &tmpval, typ),12)){
|
||
|
emit4(opc|ins|tmpval);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
switch (opc){
|
||
|
case MOV:
|
||
|
if (small((val & 0xF0000000) == 0xF0000000, 8)){
|
||
|
emit4(0xE51F0004 | (ins & 0xF000));
|
||
|
emit4(val);
|
||
|
return;
|
||
|
}
|
||
|
if (small(1,4)){
|
||
|
emit4(0xE51F0000 | (ins & 0xF000));
|
||
|
emit4(0xEA000000);
|
||
|
emit4(val);
|
||
|
return;
|
||
|
}
|
||
|
DOTVAL += 16;
|
||
|
return;
|
||
|
case ADD:
|
||
|
if (small((val & 0xF0000000) == 0xF0000000, 4)){
|
||
|
emit4(0xE51F0004 | (ins & 0xF000));
|
||
|
emit4(val);
|
||
|
emit4(0xE2800000 | (ins&0xFF000) | (ins&0xF000)>>12);
|
||
|
return;
|
||
|
}
|
||
|
emit4(0xE51F0000 | (ins & 0xF000));
|
||
|
emit4(0xEA000000);
|
||
|
emit4(val);
|
||
|
emit4(0xE2800000 | (ins&0xFF000) | (ins&0xF000)>>12);
|
||
|
return;
|
||
|
default:
|
||
|
if (pass == PASS_1)
|
||
|
DOTVAL += 16;
|
||
|
else
|
||
|
serror("immediate value out of range");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
calcimm(opc,val,typ)
|
||
|
word_t *opc;
|
||
|
valu_t *val;
|
||
|
short typ;
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
if (typ == S_UND) return 0;
|
||
|
|
||
|
if ((*val & ~0xFF) == 0) return 1;
|
||
|
|
||
|
if ((~*val & ~0xFF) == 0){
|
||
|
switch (*opc){
|
||
|
case AND:
|
||
|
*val = ~*val;
|
||
|
*opc = BIC;
|
||
|
return 1;
|
||
|
case MOV:
|
||
|
*val = ~*val;
|
||
|
*opc = MVN;
|
||
|
return 1;
|
||
|
case ADC:
|
||
|
*val = ~*val;
|
||
|
*opc = SBC;
|
||
|
return 1;
|
||
|
default :
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if ((-1**val & ~0xFF) == 0 ){
|
||
|
switch (*opc){
|
||
|
case ADD:
|
||
|
*val *= -1;
|
||
|
*opc = SUB;
|
||
|
return 1;
|
||
|
case CMP:
|
||
|
*val *= -1;
|
||
|
*opc = CMN;
|
||
|
return 1;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
do{
|
||
|
rotateleft2(&*val);
|
||
|
i++;
|
||
|
if((*val & ~0xFF) == 0){
|
||
|
*val = *val|i<<8;
|
||
|
return 1;
|
||
|
}
|
||
|
if ((~*val & ~0xFF) == 0){
|
||
|
switch (*opc){
|
||
|
case AND:
|
||
|
*val = ~*val|i<<8;
|
||
|
*opc = BIC;
|
||
|
return 1;
|
||
|
case MOV:
|
||
|
*val = ~*val|i<<8;
|
||
|
*opc = MVN;
|
||
|
return 1;
|
||
|
case ADC:
|
||
|
*val = ~*val|i<<8;
|
||
|
*opc = SBC;
|
||
|
return 1;
|
||
|
default :
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}while(i<15);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
word_t
|
||
|
calcoffset(val)
|
||
|
valu_t val;
|
||
|
{
|
||
|
if((val & ~0xFFF) == 0)
|
||
|
return(val|0x00800000);
|
||
|
val *= -1;
|
||
|
if((val & ~0xFFF) == 0)
|
||
|
return(val);
|
||
|
serror("offset out of range");
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
word_t
|
||
|
calcaddress(val,typ,reg)
|
||
|
valu_t val;
|
||
|
short typ;
|
||
|
word_t reg;
|
||
|
{
|
||
|
int tmpval;
|
||
|
|
||
|
if (typ == S_UND){
|
||
|
DOTVAL += 8;
|
||
|
return 0;
|
||
|
}
|
||
|
tmpval = val - DOTVAL - 8;
|
||
|
if(small((tmpval & ~0xFFF) == 0, 8))
|
||
|
return(val|0x008F0000);
|
||
|
tmpval *= -1;
|
||
|
if(small((tmpval & ~0xFFF) == 0, 8))
|
||
|
return(val|0x000F0000);
|
||
|
emit4(0xE51F0004 | reg << 12);
|
||
|
emit4(val | 0xF0000000);
|
||
|
return(reg << 16);
|
||
|
}
|
||
|
|
||
|
word_t
|
||
|
calcadr(reg, val, typ)
|
||
|
word_t reg;
|
||
|
valu_t val;
|
||
|
short typ;
|
||
|
{
|
||
|
valu_t tmpval = val;
|
||
|
int i = 0;
|
||
|
|
||
|
if ((val & 0xFC000000) && (typ != S_UND)){
|
||
|
serror("address out of range");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (typ != S_ABS){
|
||
|
tmpval = val-DOTVAL-8;
|
||
|
if (small((tmpval & ~0xFF) == 0),12){
|
||
|
emit4(0xE2000000|ADD|0xF<<16|reg<<12|tmpval);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
tmpval *= -1;
|
||
|
if (small((tmpval & ~0xFF) == 0), 12){
|
||
|
emit4(0xE2000000|SUB|0xF<<16|reg<<12|tmpval);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data(MOV, 0xE2000000||reg<<12, val, typ);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
word_t
|
||
|
calcshft(val, typ, styp)
|
||
|
valu_t val;
|
||
|
short typ;
|
||
|
word_t styp;
|
||
|
{
|
||
|
if (typ=S_UND) return 0;
|
||
|
if (val & ~0x1F) serror("shiftcount out of range");
|
||
|
if (styp && !val) warning("shiftcount 0");
|
||
|
return((val & 0x1F)<<7);
|
||
|
}
|
||
|
|
||
|
rotateleft2(x)
|
||
|
long *x;
|
||
|
{
|
||
|
unsigned long bits;
|
||
|
|
||
|
bits = *x & 0xC0000000;
|
||
|
*x <<= 2 ;
|
||
|
if (bits){
|
||
|
bits >>= 30;
|
||
|
*x |= bits;
|
||
|
}
|
||
|
return;
|
||
|
}
|