home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * option.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <ctype.h>
- #include "option.h"
- #include "error.h"
- #include "input.h"
-
- extern int pedantic;
-
- static WORD getCond(void)
- {
- WORD cc;
- switch(inputLook()) {
- case 'a':case 'A':
- switch(inputLookN(1)) {
- case 'l':case 'L': cc = AL; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'c':case 'C':
- switch(inputLookN(1)) {
- case 'c':case 'C': cc = CC; inputSkipN(2); break;
- case 's':case 'S': cc = CS; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'e':case 'E':
- switch(inputLookN(1)){
- case 'q':case 'Q': cc = EQ; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'g':case 'G':
- switch(inputLookN(1)) {
- case 'e':case 'E': cc = GE; inputSkipN(2); break;
- case 't':case 'T': cc = GT; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'h':case 'H':
- switch(inputLookN(1)) {
- case 'i':case 'I': cc = HI; inputSkipN(2); break;
- case 's':case 'S': cc = HS; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'l':case 'L':
- switch(inputLookN(1)) {
- case 'e':case 'E': cc = LE; inputSkipN(2); break;
- case 'o':case 'O': cc = LO; inputSkipN(2); break;
- case 's':case 'S': cc = LS; inputSkipN(2); break;
- case 't':case 'T': cc = LT; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'm':case 'M':
- switch(inputLookN(1)) {
- case 'i':case 'I': cc = MI; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'n':case 'N':
- switch(inputLookN(1)) {
- case 'e':case 'E': cc = NE; inputSkipN(2); break;
- case 'v':case 'V': cc = NV; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'p':case 'P':
- switch(inputLookN(1)) {
- case 'l':case 'L': cc = PL; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- case 'v':case 'V':
- switch(inputLookN(1)) {
- case 'c':case 'C': cc = VC; inputSkipN(2); break;
- case 's':case 'S': cc = VS; inputSkipN(2); break;
- default: cc = AL;
- }
- break;
- default: cc = AL;
- }
- return cc;
- }
-
- static WORD getDir(BOOL ldm)
- {
- WORD dir;
- switch(inputLook()) {
- case 'd':case 'D':
- switch(inputLookN(1)) {
- case 'b':case 'B': dir = DB; inputSkipN(2); break;
- case 'a':case 'A': dir = DA; inputSkipN(2); break;
- default: goto illegal;
- }
- break;
- case 'e':case 'E':
- switch(inputLookN(1)) {
- case 'd':case 'D': dir = (ldm?IB:DA); inputSkipN(2); break;
- case 'a':case 'A': dir = (ldm?DB:IA); inputSkipN(2); break;
- default: goto illegal;
- }
- break;
- case 'f':case 'F':
- switch(inputLookN(1)) {
- case 'd':case 'D': dir = (ldm?IA:DB); inputSkipN(2); break;
- case 'a':case 'A': dir = (ldm?DA:IB); inputSkipN(2); break;
- default: goto illegal;
- }
- break;
- case 'i':case 'I':
- switch(inputLookN(1)) {
- case 'b':case 'B': dir = IB; inputSkipN(2); break;
- case 'a':case 'A': dir = IA; inputSkipN(2); break;
- default: goto illegal;
- }
- break;
- default:
- illegal:
- return optionError;
- }
- return dir;
- }
-
- static WORD getPrec(int P)
- {
- switch(inputGet()) {
- case 's': case 'S': return P?PRECISION_MEM_SINGLE:PRECISION_SINGLE;
- case 'd': case 'D': return P?PRECISION_MEM_DOUBLE:PRECISION_DOUBLE;
- case 'e': case 'E': return P?PRECISION_MEM_EXTENDED:PRECISION_EXTENDED;
- case 'p': case 'P': return P?PRECISION_MEM_PACKED:optionError;
- }
- return optionError;
- }
-
- static WORD getRound(void)
- {
- switch(inputLook()) {
- case 'p': case 'P': inputSkip(); return ROUND_PLUSINF;
- case 'm': case 'M': inputSkip(); return ROUND_MINUSINF;
- case 'z': case 'Z': inputSkip(); return ROUND_ZERO;
- }
- return ROUND_NEAREST;
- }
-
- static WORD isOK(WORD option)
- {
- if(!isspace(inputGet()))
- return optionError;
- else
- return option;
- }
- WORD optionCond(void)
- {
- return isOK(getCond());
- }
-
- WORD optionCondS(void)
- {
- WORD option = getCond();
- if(inputLook() == 's' || inputLook() == 'S') {
- option |= S_FLAG;
- inputSkip();
- }
- return isOK(option);
- }
-
- WORD optionCondSP(void)
- {
- WORD option = getCond() | S_FLAG;
- if(inputLook() == 's' || inputLook() == 'S') {
- inputSkip();
- if(pedantic) error(ErrorInfo,TRUE,"S is implicit in test instructions.");
- }
- if(inputLook() == 'p' || inputLook() == 'P') {
- option |= P_FLAG;
- inputSkip();
- }
- return isOK(option);
- }
-
- WORD optionCondB(void)
- {
- WORD option = getCond();
- if(inputLook() == 'b' || inputLook() == 'B') {
- option |= B_FLAG;
- inputSkip();
- }
- return isOK(option);
- }
-
- WORD optionCondBT(void)
- {
- WORD option = getCond();
- if(inputLook() == 'b' || inputLook() == 'B') {
- option |= B_FLAG;
- inputSkip();
- }
- if(inputLook() == 't' || inputLook() == 'T') {
- option |= T_FLAG;
- inputSkip();
- }
- return isOK(option);
- }
-
- WORD optionCondDirLdm(void)
- {
- WORD option = getCond();
- if(optionError == (option |= getDir(TRUE)))
- return optionError;
- return isOK(option);
- }
-
- WORD optionCondDirStm(void)
- {
- WORD option = getCond();
- if(optionError == (option |= getDir(FALSE)))
- return optionError;
- return isOK(option);
- }
-
- WORD optionCondPrecRound(void)
- {
- WORD option = getCond();
- if(optionError == (option |= getPrec(FALSE)))
- return optionError;
- return isOK(option | getRound());
- }
-
- WORD optionCondPrec_P(void)
- {
- WORD option = getCond();
- if(optionError == (option |= getPrec(TRUE)))
- return optionError;
- return isOK(option);
- }
-
- WORD optionCondL(void)
- {
- WORD option = getCond();
- if(inputLook() == 'l' || inputLook() == 'L') {
- option |= L_FLAG;
- inputSkip();
- }
- return isOK(option);
- }
-
- /****** Trouble mnemonics **********/
-
- WORD optionLinkCond(void) /* 'b' is matched before call */
- {
- if(inputLook() != 'l' && inputLook() != 'L') { /* Only b.CC possible */
- return isOK(getCond());
- } else {
- inputSkip(); /* bl.CC or b.l? */
- switch(inputLook()) {
- case 'e':case 'E': /* b.le or bl.eq */
- inputSkip();
- switch(inputLook()) {
- case 'q': case 'Q': /* Only bl.eq */
- inputSkip();
- return isOK(EQ|LINK_BIT);
- default: /* Only b.le */
- return isOK(LE);
- }
- case 'o':case 'O': /* Only b.lo possible */
- inputSkip();
- return isOK(LO);
- case 's':case 'S': /* Only b.ls possible */
- inputSkip();
- return isOK(LS);
- case 't':case 'T': /* Only b.lt possible */
- inputSkip();
- return isOK(LT);
- default: /* Only bl.CC possible */
- return isOK(getCond() | LINK_BIT);
- }
- }
- return optionError;
- }
-
- WORD optionExceptionCond(void)
- {
- int c;
- if(inputLook() != 'e' && inputLook() != 'E') { /* Only cmf.CC possible */
- return isOK(getCond());
- } else { /* cmf.eq or cmfe.CC */
- inputSkip();
- if((c=inputLook()) == 'q' || c == 'Q') { /* Only cmf.eq */
- inputSkip();
- return isOK(EQ);
- } else { /* Only cmfe.CC */
- return isOK(getCond()|EXEPTION_BIT);
- }
- }
- return optionError;
- }
-