+/* $Header; mach0.c, v1.1 20-Oct-88 AJM */
+
#define LISTING
#define ASLD
#define THREE_PASS
+#define WORDS_REVERSED
+#define BYTES_REVERSED
+
#undef valu_t
#define valu_t long
+/* $Header: mach2.c, V1.3 2-Nov-88 AJM */
%token <y_word> COND
%token <y_word> LINK
%token <y_word> BRANCH
%token <y_word> PEE
%token <y_word> REG
%token <y_word> SHIFT
-%token <y_word> RXX
+%token <y_word> RRX
%token <y_word> SDT
%token <y_word> BYTE
%token <y_word> TRANS
%token <y_word> BDT
%token <y_word> SWI
%token <y_word> ADR
+%token <y_word> MUL
+%token <y_word> MLA
%type <y_word> optlink optcond opts optt optp optb optexc reglist rlist
%type <y_word> optsign optpsr optshift shftcnt address offset
+/* $Header: mach3.c, v1.5 2-Nov-88 AJM */
+
0, COND, 0x00000000, ".EQ",
0, COND, 0x10000000, ".NE",
0, COND, 0x20000000, ".CS",
0, SHIFT, 0x00000040, "ASR",
0, SHIFT, 0x00000060, "ROR",
-0, RXX, 0x00000060, "RXX",
+0, RRX, 0x00000060, "RRX",
0, SDT, 0x04100000, "LDR",
0, SDT, 0x04000000, "STR",
0, BDT, 0x08000000, "STMED",
0, BDT, 0x08800000, "STMEA",
-0, SWI, 0, "SWI",
+0, SWI, 0x0F000000, "SWI",
0, ADR, 0, "ADR",
+0, MUL, 0x00000090, "MUL",
+0, MLA, 0x00200090, "MLA",
+
+/* $Header: mach4.c, v1.5 2-Nov-88 AJM */
+
operation : BRANCH optlink expr
{branch($1, $2, $3.val);}
| DATA1 optcond opts optp REG ',' REG ',' operand
| BDT optcond REG optexc ',' reglist optpsr
{emit4($1|$2|$3<<16|$4|$6|$7);}
| SWI optcond expr
- {emit4($1|$2);}
- | ADR REG ',' expr
- {calcadr($2, $4.val, $4.typ);}
+ {emit4($1|$2|$3.val);}
+ | ADR optcond REG ',' expr
+ {calcadr($2, $3, $5.val, $5.typ);}
+ | MUL optcond REG ',' REG ',' REG
+ {emit4($1|$2|$3<<16|$5|$7<<8);}
+ | MLA optcond REG ',' REG ',' REG ',' REG
+ {emit4($1|$2|$3<<16|$5|$7<<8|$9<<12);}
;
optlink : {$$=0;}
optshift : ',' SHIFT shftcnt
{$$ = $2|$3;}
- | ',' RXX
+ | ',' RRX
{$$ = $2;}
|
{$$ = 0;}
+/* $Header: mach5.c, v1.6 3-Nov-88 AJM */
+
branch(brtyp, link, val)
word_t brtyp;
word_t link;
}
data(opc, ins, val, typ)
-word_t opc, ins;
+long opc, ins;
valu_t val;
short typ;
{
return;
}
- if (opc == MOV) {
+ if (opc == MOV && typ != S_ABS)
+ {
if (small((val & 0xF0000000) == 0xF0000000, 8)){
emit4(0xE51F0004 | (ins & 0xF000));
emit4(val);
DOTVAL += 16;
return;
}
- if (opc == ADD) {
+ if (opc == ADD && typ != S_ABS)
+ {
if (small((val & 0xF0000000) == 0xF0000000, 4)){
emit4(0xE51F0004 | (ins & 0xF000));
emit4(val);
emit4(0xE2800000 | (ins&0xFF000) | (ins&0xF000)>>12);
return;
}
- if (pass == PASS_1)
- DOTVAL += 16;
- else
- serror("immediate value out of range");
+ /* default: */
+ if (pass == PASS_1)
+ DOTVAL += 16;
+ else
+ serror("immediate value out of range");
+ return;
+
}
calcimm(opc,val,typ)
if (typ == S_UND) return 0;
- if ((*val & ~0xFF) == 0) return 1;
+ if ((*val & 0xFFFFFF00) == 0) return 1;
- if ((~*val & ~0xFF) == 0){
- if (*opc == AND) {
+ if ((~*val & 0xFFFFFF00) == 0){
+ if (*opc == AND)
+ {
*val = ~*val;
*opc = BIC;
return 1;
- }
- if (*opc == MOV) {
+ }
+ if (*opc == MOV)
+ {
*val = ~*val;
*opc = MVN;
return 1;
- }
- if (*opc == ADC) {
+ }
+ if (*opc == ADC)
+ {
*val = ~*val;
*opc = SBC;
return 1;
- }
+ }
+
}
- if ((-1**val & ~0xFF) == 0 ){
- if (*opc == ADD) {
+ if ((-1**val & 0xFFFFFF00) == 0 ){
+ if (*opc == ADD)
+ {
*val *= -1;
*opc = SUB;
return 1;
- }
- if (*opc == CMP) {
+ }
+ if (*opc == CMP)
+ {
*val *= -1;
*opc = CMN;
return 1;
- }
+ }
}
do{
rotateleft2(&*val);
i++;
- if((*val & ~0xFF) == 0){
+ if((*val & 0xFFFFFF00) == 0){
*val = *val|i<<8;
return 1;
}
- if ((~*val & ~0xFF) == 0){
- if (*opc == AND) {
+ if ((~*val & 0xFFFFFF00) == 0){
+ if (*opc == AND)
+ {
*val = ~*val|i<<8;
*opc = BIC;
return 1;
- }
- if (*opc == MOV) {
+ }
+ if (*opc == MOV)
+ {
*val = ~*val|i<<8;
*opc = MVN;
return 1;
- }
- if (*opc == ADC) {
+ }
+ if (*opc == ADC)
+ {
*val = ~*val|i<<8;
*opc = SBC;
return 1;
- }
+ }
}
}while(i<15);
calcoffset(val)
valu_t val;
{
- if((val & ~0xFFF) == 0)
+ if((val & 0xFFFFF000) == 0)
return(val|0x00800000);
val *= -1;
- if((val & ~0xFFF) == 0)
+ if((val & 0xFFFFF000) == 0)
return(val);
serror("offset out of range");
return(0);
}
word_t
-calcaddress(val,typ,reg)
+calcaddress (val,typ,reg)
valu_t val;
short typ;
word_t reg;
return 0;
}
tmpval = val - DOTVAL - 8;
- if(small((tmpval & ~0xFFF) == 0, 8))
+ if(small((tmpval & 0xFFFFF000) == 0, 8))
return(val|0x008F0000);
tmpval *= -1;
- if(small((tmpval & ~0xFFF) == 0, 8))
+ if(small((tmpval & 0xFFFFF000) == 0, 8))
return(val|0x000F0000);
emit4(0xE51F0004 | reg << 12);
emit4(val | 0xF0000000);
}
word_t
-calcadr(reg, val, typ)
-word_t reg;
+calcadr(ins, reg, val, typ)
+word_t ins, reg;
valu_t val;
short typ;
{
valu_t tmpval = val;
+ word_t opc;
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|(long)0xF<<16|reg<<12|tmpval);
- return 0;
+ if (tmpval > 0) {
+ if (small((tmpval & 0xFFFFFF00) == 0),12){
+ emit4(ins|ADD|0x020F0000|reg<<12|tmpval);
+ return 0;
+ }
}
tmpval *= -1;
- if (small((tmpval & ~0xFF) == 0), 12){
- emit4(0xE2000000|SUB|(long)0xF<<16|reg<<12|tmpval);
+ if (small((tmpval & 0xFFFFFF00) == 0), 12){
+ emit4(ins|SUB|0x020F0000|reg<<12|tmpval);
return 0;
}
}
- data(MOV, 0xE2000000||reg<<12, val, typ);
+ tmpval = val;
+ opc = MOV;
+ if (calcimm(&opc, &tmpval, typ)){
+ emit4(ins|opc|0x020F0000|reg<<12|tmpval);
+ return 0;
+ }
- return 0;
+/* Failed */
+ if (pass == PASS_1)
+ DOTVAL += 16;
+ else
+ serror("illegal ADR argument");
+ return ;
}
word_t styp;
{
if (typ=S_UND) return 0;
- if (val & ~0x1F) serror("shiftcount out of range");
+ if (val & 0xFFFFFFE0) serror("shiftcount out of range");
if (styp && !val) warning("shiftcount 0");
return((val & 0x1F)<<7);
}