-int risccg(int state) {
- unsigned short parm; // Opcode parameters
- unsigned type; // Opcode type
- int reg1; // Register 1
- int reg2; // Register 2
- int val = 0; // Constructed value
- char scratch[80];
- SYM *ccsym;
- SYM *sy;
- int i; // Iterator
- int t, c;
- WORD tdb;
- unsigned locptr = 0; // Address location pointer
- unsigned page_jump = 0; // Memory page jump flag
- VALUE eval; // Expression value
- WORD eattr; // Expression attributes
- SYM *esym; // External symbol involved in expr.
- TOKEN r_expr[EXPRSIZE]; // Expression token list
- WORD defined; // Symbol defined flag
- WORD attrflg;
- int indexed; // Indexed register flag
-
- parm = (WORD)(roptbl[state-3000].parm); // Get opcode parameter and type
- type = roptbl[state-3000].typ;
-
- // Detect whether the opcode parmeter passed determines that the opcode is specific to only one
- // of the RISC processors and ensure it is legal in the current code section.
- // If not then error and return.
- if(((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu) ) {
- error("opcode is not valid in this code section");
- return(ERROR);
- }
-
- // Process RISC opcode
- switch(type) {
- // No operand instructions
- // NOP
- case RI_NONE:
- risc_instruction_word(parm, 0, 0);
- break;
- // Single operand instructions (Rd)
- // ABS, MIRROR, NEG, NOT, PACK, RESMAC, SAT8, SAT16, SAT16S, SAT24, SAT32S, UNPACK
- case RI_ONE:
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, parm >> 6, reg2);
- break;
- // Two operand instructions (Rs,Rd)
- // ADD, ADDC, AND, CMP, DIV, IMACN, IMULT, IMULTN, MOVEFA, MOVETA, MULT, MMULT,
- // MTOI, NORMI, OR, ROR, SH, SHA, SUB, SUBC, XOR
- case RI_TWO:
- if(parm == 37) altbankok = 1; // MOVEFA
- reg1 = getregister(FU_REGONE);
- CHECK_COMMA;
- if(parm == 36) altbankok = 1; // MOVETA
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, reg1, reg2);
- break;
- // Numeric operand (n,Rd) where n = -16..+15
- // CMPQ
- case RI_NUM_15:
- // Numeric operand (n,Rd) where n = 0..31
- // BCLR, BSET, BTST, MOVEQ
- case RI_NUM_31:
- // Numeric operand (n,Rd) where n = 1..32
- // ADDQ, ADDQMOD, ADDQT, SHARQ, SHLQ, SHRQ, SUBQ, SUBQMOD, SUBQT, ROLQ, RORQ
- case RI_NUM_32:
- switch(type) {
- case RI_NUM_15: reg1 = -16; reg2 = 15; attrflg = FU_NUM15; break;
- default:
- case RI_NUM_31: reg1 = 0; reg2 = 31; attrflg = FU_NUM31; break;
- case RI_NUM_32: reg1 = 1; reg2 = 32; attrflg = FU_NUM32; break;
- }
- if(parm & SUB32) attrflg |= FU_SUB32;
- if(*tok == '#') {
- ++tok;
- if(expr(r_expr, &eval, &eattr, &esym) != OK)
- goto malformed;
- else {
- defined = (WORD)(eattr & DEFINED);
- if((challoc - ch_size) < 4)
- chcheck(4L);
- if(!defined) {
- fixup((WORD)(FU_WORD|attrflg), sloc, r_expr);
- reg1 = 0;
- } else {
- if((int)eval < reg1 || (int)eval > reg2) {
- error("constant out of range");
- return(ERROR);
- }
- if(parm & SUB32)
- reg1 = 32 - eval;
- else if(type == RI_NUM_32)
- reg1 = (reg1 == 32) ? 0 : eval;
- else
- reg1 = eval;
- }
- }
- } else goto malformed;
- CHECK_COMMA;
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, reg1, reg2);
- break;
- // Move Immediate - n,Rn - n in Second Word
- case RI_MOVEI:
- if(*tok == '#') {
- ++tok;
- if(expr(r_expr, &eval, &eattr, &esym) != OK) {
- malformed:
- error("malformed opcode");
- return(ERROR);
- } else {
- // Opcode tracking for nop padding
- previousop = currentop;
- currentop = parm;
- // JUMP or JR
- if((previousop == 52) || (previousop == 53) && !jpad) {
- warn("NOP inserted before MOVEI instruction.");
- D_word(0xE400);
- }
- tdb = (WORD)(eattr & TDB);
- defined = (WORD)(eattr & DEFINED);
- if((challoc - ch_size) < 4)
- chcheck(4L);
- if(!defined) {
- fixup(FU_LONG|FU_MOVEI, sloc + 2, r_expr);
- eval = 0;
- } else {
- if(tdb) {
- rmark(cursect, sloc + 2, tdb, MLONG|MMOVEI, NULL);
- }
- }
- val = eval;
- // Store the defined flags and value of the movei when used in mjump
- if(mjump_align) {
- mjump_defined = defined;
- mjump_dest = val;
- }
- }
- } else goto malformed;
- ++tok;
- reg2 = getregister(FU_REGTWO);
- at_eol();
- D_word((((parm & 0x3F) << 10) + reg2));
- val = ((val >> 16) & 0x0000FFFF) | ((val << 16) & 0xFFFF0000);
- D_long(val);
- break;
- case RI_MOVE: // PC,Rd or Rs,Rd
- if(*tok == KW_PC) {
- parm = 51;
- reg1 = 0;
- ++tok;
- } else {
- parm = 34;
- reg1 = getregister(FU_REGONE);
- }
- CHECK_COMMA;
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, reg1, reg2);
- break;
- // (Rn),Rn = 41 / (R14/R15+n),Rn = 43/44 / (R14/R15+Rn),Rn = 58/59
- case RI_LOAD:
- indexed = 0;
- parm = 41;
- if(*tok != '(') goto malformed;
- ++tok;
- if((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')'))
- indexed = (*tok - KW_R0);
- if(*tok == SYMBOL) {
- sy = lookup((char *)tok[1], LABEL, 0);
- if(!sy) {
- error(reg_err);
- return(ERROR);
- }
- if(sy->sattre & EQUATEDREG)
- if(((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) && (*(tok+2) != ')')) {
- indexed = (sy->svalue & 0x1F);
- ++tok;
- }
- }
- if(!indexed) {
- reg1 = getregister(FU_REGONE);
- } else {
- reg1 = indexed;
- indexed = 0;
- ++tok;
- if(*tok == '+') {
- parm = (WORD)(reg1 - 14 + 58);
- tok++;
- if(*tok >= KW_R0 && *tok <= KW_R31) {
- indexed = 1;
- }
- if(*tok == SYMBOL) {
- sy = lookup((char *)tok[1], LABEL, 0);
- if(!sy) {
- error(reg_err);
- return(ERROR);
- }
- if(sy->sattre & EQUATEDREG) {
- indexed = 1;
- }
- }
- if(indexed) {
- reg1 = getregister(FU_REGONE);
- } else {
- if(expr(r_expr, &eval, &eattr, &esym) != OK) {
- goto malformed;
- } else {
- tdb = (WORD)(eattr & TDB);
- defined = (WORD)(eattr & DEFINED);
- if((challoc - ch_size) < 4)
- chcheck(4L);
- if(!defined) {
- error("constant expected");
- return(ERROR);
- //fixup(FU_WORD|FU_REGONE, sloc, r_expr);
- reg1 = 0;
- } else {
- reg1 = eval;
- if(reg1 == 0) {
- reg1 = 14+(parm-58);
- parm = 41;
- warn("NULL offset removed");
- } else {
- if(reg1 < 1 || reg1 > 32) {
- error("constant out of range");
- return(ERROR);
- }
- if(reg1 == 32) reg1 = 0;
- parm = (WORD)(parm - 58 + 43);
- }
- }
- }
- }
- } else {
- reg1 = getregister(FU_REGONE);
- }
- }
- if(*tok != ')') goto malformed;
- ++tok;
- CHECK_COMMA;
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, reg1, reg2);
- break;
- // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61
- case RI_STORE:
- parm = 47;
- reg1 = getregister(FU_REGONE);
- CHECK_COMMA;
- if(*tok != '(') goto malformed;
- ++tok;
- indexed = 0;
- if((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')'))
- indexed = (*tok - KW_R0);
- if(*tok == SYMBOL) {
- sy = lookup((char *)tok[1], LABEL, 0);
- if(!sy) {
- error(reg_err);
- return(ERROR);
- }
- if(sy->sattre & EQUATEDREG)
- if(((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) && (*(tok+2) != ')')) {
- indexed = (sy->svalue & 0x1F);
- ++tok;
- }
- }
- if(!indexed) {
- reg2 = getregister(FU_REGTWO);
- } else {
- reg2 = indexed;
- indexed = 0;
- ++tok;
- if(*tok == '+') {
- parm = (WORD)(reg2 - 14 + 60);
- tok++;
- if(*tok >= KW_R0 && *tok <= KW_R31) {
- indexed = 1;
- }
- if(*tok == SYMBOL) {
- sy = lookup((char *)tok[1], LABEL, 0);
- if(!sy) {
- error(reg_err);
- return(ERROR);
- }
- if(sy->sattre & EQUATEDREG) {
- indexed = 1;
- }
- }
- if(indexed) {
- reg2 = getregister(FU_REGTWO);
- } else {
- if(expr(r_expr, &eval, &eattr, &esym) != OK) {
- goto malformed;
- } else {
- tdb = (WORD)(eattr & TDB);
- defined = (WORD)(eattr & DEFINED);
- if((challoc - ch_size) < 4)
- chcheck(4L);
- if(!defined) {
- fixup(FU_WORD|FU_REGTWO, sloc, r_expr);
- reg2 = 0;
- } else {
- reg2 = eval;
- if(reg2 == 0 ) {
- reg2 = 14+(parm-60);
- parm = 47;
- warn("NULL offset removed");
- } else {
- if(reg2 < 1 || reg2 > 32) {
- error("constant out of range");
- return(ERROR);
- }
- if(reg2 == 32) reg2 = 0;
- parm = (WORD)(parm - 60 + 49);
- }
- }
- }
- }
- } else {
- reg2 = getregister(FU_REGTWO);
- }
- }
- if(*tok != ')') goto malformed;
- ++tok;
- at_eol();
- risc_instruction_word(parm, reg2, reg1);
- break;
- // LOADB/LOADP/LOADW (Rn),Rn
- case RI_LOADN:
- if(*tok != '(') goto malformed;
- ++tok;
- reg1 = getregister(FU_REGONE);
- if(*tok != ')') goto malformed;
- ++tok;
- CHECK_COMMA;
- reg2 = getregister(FU_REGTWO);
- at_eol();
- risc_instruction_word(parm, reg1, reg2);
- break;
- // STOREB/STOREP/STOREW Rn,(Rn)
- case RI_STOREN:
- reg1 = getregister(FU_REGONE);
- CHECK_COMMA;
- if(*tok != '(') goto malformed;
- ++tok;
- reg2 = getregister(FU_REGTWO);
- if(*tok != ')') goto malformed;
- ++tok;
- at_eol();
- risc_instruction_word(parm, reg2, reg1);
- break;
- case RI_JR: // Jump Relative - cc,n - n=-16..+15 words, reg2=cc
- case RI_JUMP: // Jump Absolute - cc,(Rs) - reg2=cc
- // Check to see if there is a comma in the token string. If not then the JR or JUMP should
- // default to 0, Jump Always
- t = i = c = 0;
- while(t != EOL) {
- t = *(tok + i);
- if(t == ',') c = 1;
- i++;
- }
- if(c) { // Comma present in token string
- if(*tok == CONST) { // CC using a constant number
- ++tok;
- val = *tok;
- ++tok;
- CHECK_COMMA;
- } else if(*tok == SYMBOL) {
- val = 99;
- for(i = 0; i < MAXINTERNCC; i++) {
- strcpy(scratch, (char *)tok[1]);
- strtoupper(scratch);
- if(!strcmp(condname[i], scratch))
- val = condnumber[i];
- }
- if(val == 99) {
- ccsym = lookup((char *)tok[1], LABEL, 0);
- if(ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC)) {
- val = ccsym->svalue;
- } else {
- error("unknown condition code");
- return(ERROR);
- }
- }
- tok += 2;
- CHECK_COMMA;
- } else if(*tok == '(') {
- val = 0; // Jump always
- }
- } else {
- val = 0; // Jump always
- }
-
- if(val < 0 || val > 31) {
- error("condition constant out of range");
- return(ERROR);
- } else {
- reg1 = val; // Store condition code
- }
- if(type == RI_JR) { // JR cc,n
- if(expr(r_expr, &eval, &eattr, &esym) != OK)
- goto malformed;
- else {
- tdb = (WORD)(eattr & TDB);
- defined = (WORD)(eattr & DEFINED);
- if((challoc - ch_size) < 4)
- chcheck(4L);
- if(!defined) {
- if(in_main) {
- fixup(FU_WORD|FU_MJR, sloc, r_expr);
- } else {
- fixup(FU_WORD|FU_JR, sloc, r_expr);
- }
- reg2 = 0;
- } else {
- val = eval;
- if(orgactive) {
- reg2 = ((int)(val - (orgaddr + 2))) / 2;
- if((reg2 < -16) || (reg2 > 15))
- error("PC relative overflow");
- locptr = orgaddr;
- } else {
- reg2 = ((int)(val - (sloc + 2))) / 2;
- if((reg2 < -16) || (reg2 > 15))
- error("PC relative overflow");
- locptr = sloc;
- }
- }
- if(in_main) {
- if(defined) {
- if(((locptr >= 0xF03000) && (locptr < 0xF04000) && (val < 0xF03000)) ||
- ((val >= 0xF03000) && (val < 0xF04000) && (locptr < 0xF03000)) ) {
- warn("* cannot jump relative between main memory and local gpu ram");
- } else {
- page_jump = (locptr & 0xFFFFFF00) - (val & 0xFFFFFF00);
- if(page_jump) {
- if(val % 4) {
- warn("* destination address not aligned for long page jump relative, "
- "insert a \'nop\' before the destination label/address");
- }
- } else {
- if((val - 2) % 4) {
- warn("* destination address not aligned for short page jump relative, "
- "insert a \'nop\' before the destination label/address");
- }
- }
- }
- }
- }
- }
- risc_instruction_word(parm, reg2, reg1);
- } else { // JUMP cc, (Rn)
- if(*tok != '(') goto malformed;
- ++tok;
- reg2 = getregister(FU_REGTWO);
- if(*tok != ')') goto malformed;
- ++tok;
- at_eol();
- if(in_main) {
- if(!mjump_align) {
- warn("* \'jump\' is not recommended for .gpumain as destination addresses "
- "cannot be validated for alignment, use \'mjump\'");
- locptr = (orgactive) ? orgaddr : sloc;
- if(locptr % 4) {
- warn("* source address not aligned for long or short jump, "
- "insert a \'nop\' before the \'jump\'");
- }
- } else {
- if(mjump_defined) {
- locptr = (orgactive) ? orgaddr : sloc;
- page_jump = (locptr & 0xFFFFFF00) - (mjump_dest & 0xFFFFFF00);
- if(page_jump) {
- if(mjump_dest % 4) {
- warn("* destination address not aligned for long page jump, "
- "insert a \'nop\' before the destination label/address");
- }
- } else {
- if(!(mjump_dest & 0x0000000F) || ((mjump_dest - 2) % 4)) {
- warn("* destination address not aligned for short page jump, "
- "insert a \'nop\' before the destination label/address");
- }
- }
- } else {
- locptr = (orgactive) ? orgaddr : sloc;
- fwdjump[fwindex++] = locptr;
- }
- }
-
- }
- risc_instruction_word(parm, reg2, reg1);
- }
- break;
- // Should never get here :D
- default:
- error("unknown risc opcode type");
- return(ERROR);
- break;
-
- }
-
- return(0);
-}
+ parm = (WORD)(roptbl[state-3000].parm); // Get opcode parameter and type
+ type = roptbl[state-3000].typ;
+
+ // Detect whether the opcode parmeter passed determines that the opcode is specific to only one
+ // of the RISC processors and ensure it is legal in the current code section.
+ // If not then error and return.
+ if (((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu))
+ {
+ error("opcode is not valid in this code section");
+ return ERROR;
+ }
+
+ // Process RISC opcode
+ switch (type)
+ {
+ // No operand instructions
+ // NOP
+ case RI_NONE:
+ risc_instruction_word(parm, 0, 0);
+ break;
+ // Single operand instructions (Rd)
+ // ABS, MIRROR, NEG, NOT, PACK, RESMAC, SAT8, SAT16, SAT16S, SAT24, SAT32S, UNPACK
+ case RI_ONE:
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ risc_instruction_word(parm, parm >> 6, reg2);
+ break;
+ // Two operand instructions (Rs,Rd)
+ // ADD, ADDC, AND, CMP, DIV, IMACN, IMULT, IMULTN, MOVEFA, MOVETA, MULT, MMULT,
+ // MTOI, NORMI, OR, ROR, SH, SHA, SUB, SUBC, XOR
+ case RI_TWO:
+ if (parm == 37)
+ altbankok = 1; // MOVEFA
+
+ reg1 = getregister(FU_REGONE);
+ CHECK_COMMA;
+
+ if (parm == 36)
+ altbankok = 1; // MOVETA
+
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ risc_instruction_word(parm, reg1, reg2);
+ break;
+ // Numeric operand (n,Rd) where n = -16..+15
+ // CMPQ
+ case RI_NUM_15:
+ // Numeric operand (n,Rd) where n = 0..31
+ // BCLR, BSET, BTST, MOVEQ
+ case RI_NUM_31:
+ // Numeric operand (n,Rd) where n = 1..32
+ // ADDQ, ADDQMOD, ADDQT, SHARQ, SHLQ, SHRQ, SUBQ, SUBQMOD, SUBQT, ROLQ, RORQ
+ case RI_NUM_32:
+ switch (type)
+ {
+ case RI_NUM_15:
+ reg1 = -16; reg2 = 15; attrflg = FU_NUM15;
+ break;
+ default:
+ case RI_NUM_31:
+ reg1 = 0; reg2 = 31; attrflg = FU_NUM31;
+ break;
+ case RI_NUM_32:
+ reg1 = 1; reg2 = 32; attrflg = FU_NUM32;
+ break;
+ }
+
+ if (parm & SUB32) attrflg |= FU_SUB32;
+ {
+ if (*tok == '#')
+ {
+ ++tok;
+
+ if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ goto malformed;
+ else
+ {
+ defined = (WORD)(eattr & DEFINED);
+
+ if ((challoc - ch_size) < 4)
+ chcheck(4L);
+
+ if (!defined)
+ {
+ fixup((WORD)(FU_WORD|attrflg), sloc, r_expr);
+ reg1 = 0;
+ }
+ else
+ {
+ if ((int)eval < reg1 || (int)eval > reg2)
+ {
+ error("constant out of range");
+ return ERROR;
+ }
+
+ if (parm & SUB32)
+ reg1 = 32 - eval;
+ else if (type == RI_NUM_32)
+ reg1 = (reg1 == 32) ? 0 : eval;
+ else
+ reg1 = eval;
+ }
+ }
+ }
+ else
+ goto malformed;
+ }
+
+ CHECK_COMMA;
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ risc_instruction_word(parm, reg1, reg2);
+ break;
+ // Move Immediate - n,Rn - n in Second Word
+ case RI_MOVEI:
+ if (*tok == '#')
+ {
+ ++tok;
+ if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ {
+ malformed:
+ error("malformed opcode");
+ return ERROR;
+ }
+ else
+ {
+ // Opcode tracking for nop padding
+ previousop = currentop;
+ currentop = parm;
+
+ // JUMP or JR
+ if ((previousop == 52) || (previousop == 53) && !jpad)
+ {
+ warn("NOP inserted before MOVEI instruction.");
+ D_word(0xE400);
+ }
+
+ tdb = (WORD)(eattr & TDB);
+ defined = (WORD)(eattr & DEFINED);
+
+ if ((challoc - ch_size) < 4)
+ chcheck(4L);
+
+ if (!defined)
+ {
+ fixup(FU_LONG|FU_MOVEI, sloc + 2, r_expr);
+ eval = 0;
+ }
+ else
+ {
+ if (tdb)
+ {
+ rmark(cursect, sloc + 2, tdb, MLONG|MMOVEI, NULL);
+ }
+ }
+
+ val = eval;
+
+ // Store the defined flags and value of the movei when used in mjump
+ if (mjump_align)
+ {
+ mjump_defined = defined;
+ mjump_dest = val;
+ }
+ }
+ }
+ else
+ goto malformed;
+
+ ++tok;
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ D_word((((parm & 0x3F) << 10) + reg2));
+ val = ((val >> 16) & 0x0000FFFF) | ((val << 16) & 0xFFFF0000);
+ D_long(val);
+ break;
+ case RI_MOVE: // PC,Rd or Rs,Rd
+ if (*tok == KW_PC)
+ {
+ parm = 51;
+ reg1 = 0;
+ ++tok;
+ }
+ else
+ {
+ parm = 34;
+ reg1 = getregister(FU_REGONE);
+ }
+
+ CHECK_COMMA;
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ risc_instruction_word(parm, reg1, reg2);
+ break;
+ // (Rn),Rn = 41 / (R14/R15+n),Rn = 43/44 / (R14/R15+Rn),Rn = 58/59
+ case RI_LOAD:
+ indexed = 0;
+ parm = 41;
+
+ if (*tok != '(')
+ goto malformed;
+
+ ++tok;
+ if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')'))
+ indexed = (*tok - KW_R0);
+
+ if (*tok == SYMBOL)
+ {
+ sy = lookup((char *)tok[1], LABEL, 0);
+ if (!sy)
+ {
+ error(reg_err);
+ return ERROR;
+ }
+
+ if (sy->sattre & EQUATEDREG)
+ {
+ if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
+ && (*(tok+2) != ')'))
+ {
+ indexed = (sy->svalue & 0x1F);
+ ++tok;
+ }
+ }
+ }
+
+ if (!indexed)
+ {
+ reg1 = getregister(FU_REGONE);
+ }
+ else
+ {
+ reg1 = indexed;
+ indexed = 0;
+ ++tok;
+
+ if (*tok == '+')
+ {
+ parm = (WORD)(reg1 - 14 + 58);
+ tok++;
+
+ if (*tok >= KW_R0 && *tok <= KW_R31)
+ {
+ indexed = 1;
+ }
+
+ if (*tok == SYMBOL)
+ {
+ sy = lookup((char *)tok[1], LABEL, 0);
+
+ if (!sy)
+ {
+ error(reg_err);
+ return ERROR;
+ }
+
+ if (sy->sattre & EQUATEDREG)
+ {
+ indexed = 1;
+ }
+ }
+
+ if (indexed)
+ {
+ reg1 = getregister(FU_REGONE);
+ }
+ else
+ {
+ if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ {
+ goto malformed;
+ }
+ else
+ {
+ tdb = (WORD)(eattr & TDB);
+ defined = (WORD)(eattr & DEFINED);
+
+ if ((challoc - ch_size) < 4)
+ chcheck(4L);
+
+ if (!defined)
+ {
+ error("constant expected");
+ return ERROR;
+ //fixup(FU_WORD|FU_REGONE, sloc, r_expr);
+ reg1 = 0;
+ }
+ else
+ {
+ reg1 = eval;
+
+ if (reg1 == 0)
+ {
+ reg1 = 14 + (parm - 58);
+ parm = 41;
+ warn("NULL offset removed");
+ }
+ else
+ {
+ if (reg1 < 1 || reg1 > 32)
+ {
+ error("constant out of range");
+ return ERROR;
+ }
+
+ if (reg1 == 32)
+ reg1 = 0;
+
+ parm = (WORD)(parm - 58 + 43);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ reg1 = getregister(FU_REGONE);
+ }
+ }
+
+ if (*tok != ')')
+ goto malformed;
+
+ ++tok;
+ CHECK_COMMA;
+ reg2 = getregister(FU_REGTWO);
+ at_eol();
+ risc_instruction_word(parm, reg1, reg2);
+ break;
+ // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61
+ case RI_STORE:
+ parm = 47;
+ reg1 = getregister(FU_REGONE);
+ CHECK_COMMA;