From: David Given Date: Tue, 6 Sep 2016 21:58:25 +0000 (+0200) Subject: Fix load and store instructions. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=ff3c7830433e39dc9d3939c701c6df30e264f357;p=ack.git Fix load and store instructions. --HG-- branch : default-branch --- diff --git a/mach/arm/as/mach0.c b/mach/arm/as/mach0.c index ffce76480..123d08e86 100644 --- a/mach/arm/as/mach0.c +++ b/mach/arm/as/mach0.c @@ -18,6 +18,8 @@ #undef word_t #define word_t uint32_t +typedef uint32_t quad; + #undef ALIGNWORD #define ALIGNWORD 4 diff --git a/mach/arm/as/mach1.c b/mach/arm/as/mach1.c index f1eb84a4d..c552ed2c5 100644 --- a/mach/arm/as/mach1.c +++ b/mach/arm/as/mach1.c @@ -1,6 +1,5 @@ /* $Header; mach1.c, v1.1 06-Mar-89 AJM */ extern word_t opcode; -extern int success; /* LDR/STR address failure flag */ -extern void strldr(uint32_t opc, valu_t val); +extern void strldr(uint32_t opc, struct expr_t* expr); diff --git a/mach/arm/as/mach4.c b/mach/arm/as/mach4.c index c3874eec4..4f3f597c0 100644 --- a/mach/arm/as/mach4.c +++ b/mach/arm/as/mach4.c @@ -1,138 +1,116 @@ /* $Id: mach4.c, v1.9 15-Mar-89 AJM */ -operation : BRANCH optlink expr - {branch($1, $2, &$3);} - | DATA1 optcond opts optp REG ',' REG ',' operand - {data($1, $2|$3|$4|$5<<12|$7<<16, $9.val, $9.typ);} - | DATA2 optcond opts optp REG ',' operand - {data($1, $2|$3|$4|$5<<12, $7.val, $7.typ);} - | DATA3 optcond opts optp REG ',' operand - {data($1, $2|$3|$4|$5<<16, $7.val, $7.typ);} - | SDT optcond optt REG ',' address - {strldr($1|$2|$3|$4<<12,$6);} - | SDT2 optcond optt REG ',' splitaddress - {strldr($1|$2|$3|$4<<12,$6);} - | BDT optcond REG optexc ',' reglist optpsr - {emit4($1|$2|$3<<16|$4|$6|$7);} - | SWI optcond expr - {emit4($1|$2|$3.val);} - | 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;} - | LINK - {$$=$1;} - ; - -optcond : {$$=0xE0000000;} - | COND - {$$=$1;} - ; - -opts : {$$=0;} - | SET - {$$=$1;} - ; - -optt : {$$=0;} - | TRANS - {$$=$1;} - ; - -optp : {$$=0;} - | PEE - {$$=$1;} - ; - -optexc : {$$=0;} - | '<' - {$$=0x00200000;} - ; - -optpsr : {$$=0;} - | '^' - {$$=0x00400000;} - ; - -operand : REG optshift - {$$.val = $1|$2; $$.typ = S_REG;} - | '#'expr - {$$ = $2;} - ; - -optshift : ',' SHIFT shftcnt - {$$ = $2|$3;} - | ',' RRX - {$$ = $2;} - | - {$$ = 0;} - ; - -aoptshift : ',' SHIFT '#' expr - {$$ = $2|calcshft($4.val, $4.typ, $0);} - | ',' RRX - {$$ = $2;} - | - {$$ = 0;} - ; - -shftcnt : '#' expr - {$$ = calcshft($2.val, $2.typ, $0);} - | REG - {$$ = $1<<8|0x10;} - ; - -address : expr - {success = 0; $$ = $1.val;} - | '[' REG ']' - {success = 1; $$ = 0x01000000|$2<<16;} - | '[' REG ',' offset ']' optexc - {success = 1; $$ = 0x01000000|$2<<16|$4|$6;} - | '[' REG ']' ',' offset - {success = 1; $$ = $2<<16|$5;} - ; - -offset : '#' expr - {$$ = calcoffset($2.val);} - | optsign REG aoptshift - {$$ = 0x02000000|$1|$2|$3;} - ; - -splitaddress : expr - {success = 0; $$ = $1.val;} - | '[' REG ']' - {success = 1; $$ = 0x01000000|$2<<16;} - | '[' REG ',' splitoffset ']' optexc - {success = 1; $$ = 0x01000000|$2<<16|$4|$6;} - | '[' REG ']' ',' splitoffset - {success = 1; $$ = $2<<16|$5;} - ; - -splitoffset : '#' expr - {$$ = splitoffset($2.val);} - ; - -optsign : {$$ = 0x00800000;} - | '+' - {$$ = 0x00800000;} - | '-' - {$$ = 0x0;} - ; - -reglist : '{' rlist '}' - {$$ = $2;} - ; - -rlist : REG - {$$ = 1<<$1;} - | rlist ',' REG - {$$ = $1|1<<$3;} - | REG '-' REG - { - for ($$ = 0; $1 <= $3; $1++) - $$ |= (1<<$1); - } - ; +operation + : BRANCH optlink expr { branch($1, $2, &$3); } + | DATA1 optcond opts optp REG ',' REG ',' operand { data($1, $2 | $3 | $4 | $5<<12|$7<<16, $9.val, $9.typ); } + | DATA2 optcond opts optp REG ',' operand { data($1, $2 | $3 | $4 | $5<<12, $7.val, $7.typ); } + | DATA3 optcond opts optp REG ',' operand { data($1, $2 | $3 | $4 | $5<<16, $7.val, $7.typ); } + | SDT optcond optt REG ',' address { emit4($1 | $2 | $3 | $4<<12 | $6); } + | SDT2 optcond optt REG ',' splitaddress { emit4($1 | $2 | $3 | $4<<12 | $6); } + | SDT optcond optt REG ',' expr { strldr($1 | $2 | $3 | $4<<12, &$6); } + | SDT2 optcond optt REG ',' expr { strldr($1 | $2 | $3 | $4<<12, &$6); } + | BDT optcond REG optexc ',' reglist optpsr { emit4($1 | $2 | $3<<16 |$4 | $6 | $7); } + | SWI optcond expr { emit4($1 | $2 | $3.val); } + | 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; } + | LINK { $$=$1; } + ; + +optcond + : { $$=0xE0000000; } + | COND { $$=$1; } + ; + +opts + : { $$=0; } + | SET { $$=$1; } + ; + +optt + : { $$=0; } + | TRANS { $$=$1; } + ; + +optp + : { $$=0; } + | PEE { $$=$1; } + ; + +optexc + : { $$=0; } + | '<' { $$=0x00200000; } + ; + +optpsr + : { $$=0; } + | '^' { $$=0x00400000; } + ; + +operand + : REG optshift { $$.val = $1|$2; $$.typ = S_REG; } + | '#'expr { $$ = $2; } + ; + +optshift + : ',' SHIFT shftcnt { $$ = $2|$3; } + | ',' RRX { $$ = $2; } + | { $$ = 0; } + ; + +aoptshift + : ',' SHIFT '#' expr { $$ = $2|calcshft($4.val, $4.typ, $0); } + | ',' RRX { $$ = $2; } + | { $$ = 0; } + ; + +shftcnt + : '#' expr { $$ = calcshft($2.val, $2.typ, $0); } + | REG { $$ = $1<<8|0x10; } + ; + +address + : '[' REG ']' { $$ = 0x01000000|$2<<16; } + | '[' REG ',' offset ']' optexc { $$ = 0x01000000|$2<<16|$4|$6; } + | '[' REG ']' ',' offset { $$ = $2<<16|$5; } + ; + +offset + : '#' expr { $$ = calcoffset($2.val); } + | optsign REG aoptshift { $$ = 0x02000000|$1|$2|$3; } + ; + +splitaddress + : '[' REG ']' { $$ = 0x01000000|$2<<16; } + | '[' REG ',' splitoffset ']' optexc { $$ = 0x01000000|$2<<16|$4|$6; } + | '[' REG ']' ',' splitoffset { $$ = $2<<16|$5; } + ; + +splitoffset + : '#' expr { $$ = splitoffset($2.val); } + ; + +optsign + : { $$ = 0x00800000; } + | '+' { $$ = 0x00800000; } + | '-' { $$ = 0x0; } + ; + +reglist + : '{' rlist '}' { $$ = $2; } + ; + +rlist + : REG { $$ = 1<<$1; } + | rlist ',' REG { $$ = $1|1<<$3; } + | REG '-' REG + { + for ($$ = 0; $1 <= $3; $1++) + $$ |= (1<<$1); + } + ; + +// vim: set ts=4 sw=4 expandtab : diff --git a/mach/arm/as/mach5.c b/mach/arm/as/mach5.c index 97b0365b8..73f506784 100644 --- a/mach/arm/as/mach5.c +++ b/mach/arm/as/mach5.c @@ -179,37 +179,38 @@ word_t splitoffset(valu_t val) return 0; } -/* This routine deals with STR and LDR instructions */ - -void strldr(uint32_t opc, valu_t val) +void strldr(uint32_t opc, struct expr_t* expr) { + quad type = expr->typ & S_TYP; uint32_t d; + + /* Sanity checking. */ - /* If the expression was a register, then just output it and save 24 - bytes */ - - if (success) + if (type == S_ABS) + serror("can't use absolute addresses here"); + + if (type == DOTTYP) { - emit4(opc | val); - return; - } + /* Reference to code in this section. */ - d = val - DOTVAL - 8; - if (fitu(d, 12)) - { /* If it's +ve */ - emit4(opc | d | 0x018F0000); /* PC rel, up bit */ - return; - } + uint32_t d = expr->val - DOTVAL - 8; + if (fitu(d, 12)) + { /* If it's +ve */ + emit4(opc | d | 0x018F0000); /* PC rel, up bit */ + return; + } - d = -d; - if (fitu(d, 12)) - { /* If it's -ve */ - emit4(opc | d | 0x010F0000); /* PC rel, no up bit */ - return; + d = -d; + if (fitu(d, 12)) + { /* If it's -ve */ + emit4(opc | d | 0x010F0000); /* PC rel, no up bit */ + return; + } + + serror("displacement to near constant is too big"); } - serror("displacement overflow: 0x%x", d); - return; + serror("cannot directly address symbols in another section"); } word_t calcshft(valu_t val, short typ, word_t styp)