コード例 #1
0
ファイル: for.c プロジェクト: Ukusbobra/open-watcom-v2
int ForDirective( int i, enum irp_type type )
/*******************************************/
{
    int start = i - 1; /* location of "directive name .. after any labels" */
    int arg_loc;
    char *parmstring = NULL;
    char *ptr;
    char *next_parm;
    char *end_of_parms;
    char buffer[MAX_LINE_LEN];
    int len = 0;

    if( type == IRP_REPEAT ) {
        ExpandTheWorld( i, FALSE, TRUE );
        /* make a temporary macro, then call it */
        if( AsmBuffer[i]->class != TC_NUM ) {
            AsmError( OPERAND_EXPECTED );
            return( ERROR );
        }
        arg_loc = i;
        len = AsmBuffer[i]->u.value;
        i++;
        if( AsmBuffer[i]->class != TC_FINAL ) {
            AsmError( OPERAND_EXPECTED );
            return( ERROR );
        }
    } else {
コード例 #2
0
static void add_constant( char *string )
/**************************************/
{
    char *tmp;
    char *one = "1";

    tmp = strchr( string, '=' );
    if( tmp == NULL ) {
        tmp = strchr( string, '#' );
        if( tmp == NULL ) {
            tmp = one;
        } else {
            *tmp = '\0';
            tmp++;
        }
    } else {
        *tmp = '\0';
        tmp++;
    }

    if( isvalidident( string ) == ERROR ) {
        AsmError( SYNTAX_ERROR ); // fixme
        return;
    }

    StoreConstant( string, tmp, FALSE ); // don't allow it to be redef'd
}
コード例 #3
0
ファイル: main.c プロジェクト: NoSuchProcess/open-watcom-v2
static void add_constant( const char *string, bool underscored )
/**************************************************************/
{
    char    name[MAX_LINE_LEN];
    char    *tmp;
    char    c;

    tmp = name;
    if( underscored ) {
        *tmp++ = '_'; *tmp++ = '_';
    }
    while( (c = *string) != '\0' ) {
        ++string;
        if( c == '=' || c == '#' )
            break;
        *tmp++ = c;
    }
    if( underscored ) {
        *tmp++ = '_'; *tmp++ = '_';
    }
    *tmp = '\0';
    if( *string == '\0' )
        string = "1";

    if( isvalidident( name ) ) {
        AsmError( SYNTAX_ERROR ); // fixme
        return;
    }

    StoreConstant( name, string, false ); // don't allow it to be redef'd
}
コード例 #4
0
ファイル: asutils.c プロジェクト: Graham-stott/open-watcom-v2
extern void AsError( int resource_id, ... )
//*****************************************
{
    va_list     arglist;
    char        msg[ MAX_RESOURCE_SIZE ];

    va_start( arglist, resource_id );
    AsMsgGet( resource_id, AsResBuffer );
    vsprintf( msg, AsResBuffer, arglist );
    va_end( arglist );
    AsmError( msg );    // CC provides this
}
コード例 #5
0
ファイル: asmstruc.c プロジェクト: Ukusbobra/open-watcom-v2
int StructDef( int i )
/********************/
{
    char        *name;
    dir_node    *dir;
    int         n;

    if( Options.mode & MODE_IDEAL ) {
        n = i + 1;
        if( ( AsmBuffer[i]->u.token == T_STRUC ) &&
            ( AsmBuffer[n]->class != TC_ID ) ) {
            AsmError( SYNTAX_ERROR );
            return( ERROR );
        }
    } else {
コード例 #6
0
ファイル: hll.c プロジェクト: OS2World/DEV-ASM-UTIL-JWasm
static ret_code EvaluateHllExpression( hll_list * hll, int *i, int ilabel, bool is_true )
/***************************************************************************************/
{
    char *lastjmp = NULL;
    expr_list opndx;
    char buffer[MAX_LINE_LEN*2];

    DebugMsg(("EvaluateHllExpression enter\n"));

    buffer[0] = NULLC;
    if ( ERROR == GetExpression( hll, i, ilabel, is_true, buffer, &lastjmp, &opndx ) )
        return( ERROR );
    if ( buffer[0] )
        WriteExprSrc( hll, buffer );
    if ( hll->condlines != NULL && *hll->condlines == '\n' ) {
        AsmError( SYNTAX_ERROR_IN_CONTROL_FLOW_DIRECTIVE );
        return( ERROR );
    }
    return( NOT_ERROR );
}
コード例 #7
0
int conditional_assembly_directive( int i )
/*****************************************/
{
    uint_16     direct;

    direct = AsmBuffer[i]->u.value;

    switch( direct ) {
    case T_IF:
    case T_IF1:
    case T_IF2:
    case T_IFB:
    case T_IFDEF:
    case T_IFDIF:
    case T_IFDIFI:
    case T_IFE:
    case T_IFIDN:
    case T_IFIDNI:
    case T_IFNB:
    case T_IFNDEF:
        if( CurState == ACTIVE ) {
            NestLevel++;
            if( NestLevel > MAX_NESTING ) {
                /*fixme */
                AsmError( NESTING_LEVEL_TOO_DEEP );
                return( ERROR );
            }
            CurState = get_cond_state( i );
        } else {
            falseblocknestlevel++;
        }
        break;
    case T_ELSEIF:
    case T_ELSEIF1:
    case T_ELSEIF2:
    case T_ELSEIFB:
    case T_ELSEIFDEF:
    case T_ELSEIFDIF:
    case T_ELSEIFDIFI:
    case T_ELSEIFE:
    case T_ELSEIFIDN:
    case T_ELSEIFIDNI:
    case T_ELSEIFNB:
    case T_ELSEIFNDEF:
        if( CurState == ACTIVE ) {
            CurState = DONE;
        } else if( CurState == LOOKING_FOR_TRUE_COND ) {
            if( falseblocknestlevel == 0 ) {
                CurState = get_cond_state( i );
            }
        }
        break;
    case T_ELSE:
        if( CurState == ACTIVE ) {
            CurState = DONE;
        } else if( CurState == LOOKING_FOR_TRUE_COND ) {
            if( falseblocknestlevel == 0 ) {
                CurState = ACTIVE;
            }
        }
        break;
    case T_ENDIF:
        if( CurState == ACTIVE || falseblocknestlevel == 0 ) {
            NestLevel--;
            if( NestLevel < 0 ) {
                NestLevel = 0;
                AsmError( BLOCK_NESTING_ERROR );
                return( ERROR );
            }
            CurState = ACTIVE;
        } else {
            falseblocknestlevel--;
        }
        break;
    default:
        /**/
        myassert( 0 );
        return( ERROR );
    }
    return( NOT_ERROR );
}
コード例 #8
0
ファイル: asmjump.c プロジェクト: Azarien/open-watcom-v2
bool jmp( expr_list *opndx, int *flags )
/*
  determine the displacement of jmp;
*/
{
    int_32              addr;
    enum fixup_types    fixup_type;
    enum fixup_options  fixup_option;
    enum sym_state      state;
    struct asm_sym      *sym;
#if defined( _STANDALONE_ )
    dir_node            *seg;
#endif

    *flags = 0;
    Code->data[Opnd_Count] = opndx->value;
    sym = opndx->sym;
    if( sym == NULL ) {
        if( Code->info.token == T_CALL ) {
            Code->info.token = T_CALLF;
        } else if( Code->info.token == T_JMP ) {
            Code->info.token = T_JMPF;
        }
        if( Code->data[Opnd_Count] > USHRT_MAX )
            Code->info.opnd_type[Opnd_Count] = OP_I32;
        else
            Code->info.opnd_type[Opnd_Count] = OP_I16;
        return( RC_OK );
    }

#if defined( _STANDALONE_ )
    if( sym->mem_type == MT_ERROR ) {
        AsmError( LABEL_NOT_DEFINED );
        return( RC_ERROR );
    }
#endif
    state = sym->state;
#if defined( _STANDALONE_ )
    seg = GetSeg( sym );
    if( seg == NULL || CurrSeg == NULL || CurrSeg->seg != seg ) {
        /* jumps to another segment are just like to another file */
        state = SYM_EXTERNAL;
    }
#endif

    if( !Code->mem_type_fixed ) {
        Code->mem_type = MT_EMPTY;
    }
    fixup_option = OPTJ_NONE;
    fixup_type = FIX_RELOFF8;
    switch( state ) {
    case SYM_INTERNAL:
#if defined( _STANDALONE_ )
    case SYM_PROC:
#endif
        if(  ( Code->mem_type == MT_EMPTY || Code->mem_type == MT_SHORT
                || Code->mem_type == MT_NEAR )
            && sym->mem_type != MT_WORD
            && sym->mem_type != MT_DWORD
            && sym->mem_type != MT_FWORD
            && !IS_JMPCALLF( Code->info.token ) ) {
#if defined( _STANDALONE_ )
            if( ( Code->info.token == T_CALL )
                && ( Code->mem_type == MT_EMPTY )
                && ( sym->mem_type == MT_FAR ) ) {
                FarCallToNear();
                *flags = SCRAP_INSTRUCTION;
                return( RC_OK );
            }
            addr = sym->offset;
#else
            addr = sym->addr;
#endif
            addr -= ( AsmCodeAddress + 2 );  // calculate the displacement
            addr += Code->data[Opnd_Count];
            switch( Code->info.token ) {
            case T_JCXZ:
            case T_LOOPW:
            case T_LOOPEW:
            case T_LOOPZW:
            case T_LOOPNEW:
            case T_LOOPNZW:
                if( Code->use32 ) {
                    // 1 extra byte for OPNSIZ
                    addr--;
                }
                break;
            case T_JECXZ:
            case T_LOOPD:
            case T_LOOPED:
            case T_LOOPZD:
            case T_LOOPNED:
            case T_LOOPNZD:
                if( !Code->use32 ) {
                    // 1 extra byte for OPNSIZ
                    addr--;
                }
                break;
            }
            if( Code->info.token == T_CALL && Code->mem_type == MT_EMPTY ) {
                Code->mem_type = MT_NEAR;
            }
            if( Code->mem_type != MT_NEAR && Code->info.token != T_CALL
                && ( addr >= SCHAR_MIN && addr <= SCHAR_MAX ) ) {
                Code->info.opnd_type[Opnd_Count] = OP_I8;
            } else {
                /* near jmp */
                if( Code->use32 ) {
                    Code->info.opnd_type[Opnd_Count] = OP_I32;
                    addr -= 3; // 32 bit displacement
                } else {
                    Code->info.opnd_type[Opnd_Count] = OP_I16;
                    addr -= 1; // 16 bit displacement
                }
                if( IS_JMP( Code->info.token ) ) {
                    switch( Code->info.token ) {
                    case T_JMP:
                    case T_JMPF:
                    case T_JCXZ:
                    case T_JECXZ:
                        break;
                    default:
                        // 1 extra byte for opcode ( 0F )
                        addr--;
                        break;
                    }
                }
            }

            /* store the displacement */
            Code->data[Opnd_Count] = addr;

            switch( Code->info.token ) {
            case T_JCXZ:
            case T_JECXZ:
            case T_LOOP:
            case T_LOOPE:
            case T_LOOPNE:
            case T_LOOPNZ:
            case T_LOOPZ:
            case T_LOOPD:
            case T_LOOPED:
            case T_LOOPNED:
            case T_LOOPNZD:
            case T_LOOPZD:
            case T_LOOPW:
            case T_LOOPEW:
            case T_LOOPNEW:
            case T_LOOPNZW:
            case T_LOOPZW:
#if defined( _STANDALONE_ )
                if( !PhaseError && (Code->info.opnd_type[Opnd_Count] != OP_I8) ) {
#else
                if( (Code->info.opnd_type[Opnd_Count] != OP_I8) ) {
#endif
                    AsmError( JUMP_OUT_OF_RANGE );
                    return( RC_ERROR );
                }
                Code->info.opnd_type[Opnd_Count] = OP_I8;
                break;
            }

            if( (Code->info.cpu&P_CPU_MASK) < P_386 && IS_JMP( Code->info.token ) ) {
                /* look into jump extension */
                switch( Code->info.token ) {
                case T_JMP:
                case T_JMPF:
                    break;
                default:
                    if( Code->info.opnd_type[Opnd_Count] != OP_I8 ) {
#if defined( _STANDALONE_ )
                        if( Code->mem_type == MT_EMPTY ) {
                            jumpExtend( 0 );
                            *flags = SCRAP_INSTRUCTION;
                            return( RC_OK );
                        } else if( !PhaseError ) {
                            AsmError( JUMP_OUT_OF_RANGE );
                            return( RC_ERROR );
                        }
#else
                        AsmError( JUMP_OUT_OF_RANGE );
                        return( RC_ERROR );
#endif
                    }
                }
            }
            break;
        }
        /* otherwise fall through & get handled like external symbols */
    case SYM_UNDEFINED:
    case SYM_EXTERNAL:

        /* forward ref, or external symbol */
        if( Code->mem_type == MT_EMPTY && sym->mem_type != MT_EMPTY ) {
            switch( sym->mem_type ) {
            case MT_FAR:
                if( Code->info.token == T_CALL ) {
                    Code->info.token = T_CALLF;
                } else if( Code->info.token == T_JMP ) {
                    Code->info.token = T_JMPF;
                }
                // fall through
            case MT_SHORT:
            case MT_NEAR:
                Code->mem_type = sym->mem_type;
                break;
#if defined( _STANDALONE_ )
            case MT_PROC:
                if( IS_PROC_FAR() ) {
                    Code->mem_type = MT_FAR;
                    if( Code->info.token == T_CALL ) {
                        Code->info.token = T_CALLF;
                    } else if( Code->info.token == T_JMP ) {
                        Code->info.token = T_JMPF;
                    }
                } else {
                    Code->mem_type = MT_NEAR;
                }
                break;
#endif
            case MT_FWORD:
                if( ptr_operator( MT_FWORD, true ) )
                    return( RC_ERROR );
                break;
            default:
                Code->mem_type = sym->mem_type;
            }
        }
        if( Code->mem_type == MT_FAR ) {
            if( Code->info.token == T_CALL ) {
                Code->info.token = T_CALLF;
            } else if( Code->info.token == T_JMP ) {
                Code->info.token = T_JMPF;
            }
        }
        switch( Code->info.token ) {
        case T_CALLF:
        case T_JMPF:
            switch( Code->mem_type ) {
            case MT_SHORT:
            case MT_NEAR:
                if( Opnd_Count == OPND1 && Code->mem_type_fixed ) {
                    AsmError( CANNOT_USE_SHORT_OR_NEAR );
                    return( RC_ERROR );
                }
                /* fall through */
            case MT_FAR:
            case MT_EMPTY:
#if defined( _STANDALONE_ )
                SET_OPSIZ( Code, SymIs32( sym ));
                find_frame( sym );
#endif
                if( Opnd_Count == OPND2 ) {
                    if( IS_OPSIZ_32( Code ) ) {
                        fixup_type = FIX_OFF32;
                        Code->info.opnd_type[Opnd_Count] = OP_I32;
                    } else {
                        fixup_type = FIX_OFF16;
                        Code->info.opnd_type[Opnd_Count] = OP_I16;
                    }
                } else {
                    if( IS_OPSIZ_32( Code ) ) {
                        fixup_type = FIX_PTR32;
                        Code->info.opnd_type[Opnd_Count] = OP_J48;
                    } else {
                        fixup_type = FIX_PTR16;
                        Code->info.opnd_type[Opnd_Count] = OP_J32;
                    }
                }
                break;
            case MT_BYTE:
            case MT_WORD:
#if defined( _STANDALONE_ )
            case MT_SBYTE:
            case MT_SWORD:
#endif
                AsmError( INVALID_SIZE );
                return( RC_ERROR );
            case MT_DWORD:
            case MT_FWORD:
#if defined( _STANDALONE_ )
            case MT_SDWORD:
#endif
                *flags = INDIRECT_JUMP;
                return( RC_OK );
            case MT_QWORD:
            case MT_TBYTE:
            case MT_OWORD:
                AsmError( INVALID_SIZE );
                return( RC_ERROR );
            }
            break;
        case T_CALL:
            if( Code->mem_type == MT_SHORT ) {
                AsmError( CANNOT_USE_SHORT_WITH_CALL );
                return( RC_ERROR );
            } else if( Code->mem_type == MT_EMPTY ) {
#if defined( _STANDALONE_ )
                fixup_option = OPTJ_CALL;
#else
                fixup_option = OPTJ_NONE;
#endif
                if( Code->use32 ) {
                    fixup_type = FIX_RELOFF32;
                    Code->info.opnd_type[Opnd_Count] = OP_I32;
                } else {
                    fixup_type = FIX_RELOFF16;
                    Code->info.opnd_type[Opnd_Count] = OP_I16;
                }
                break;
            }
            /* fall through */
        case T_JMP:
            switch( Code->mem_type ) {
            case MT_SHORT:
                fixup_option = OPTJ_EXPLICIT;
                fixup_type = FIX_RELOFF8;
                Code->info.opnd_type[Opnd_Count] = OP_I8;
                break;
            case MT_FAR:
                AsmError( SYNTAX_ERROR );
                break;
            case MT_EMPTY:
                // forward reference
                // inline assembler jmp default distance is near
                // stand-alone assembler jmp default distance is short
                fixup_option = OPTJ_NONE;
#if defined( _STANDALONE_ )
                /* guess short if JMP, we will expand later if needed */
                fixup_type = FIX_RELOFF8;
                Code->info.opnd_type[Opnd_Count] = OP_I8;
#else
                if( Code->use32 ) {
                    fixup_type = FIX_RELOFF32;
                    Code->info.opnd_type[Opnd_Count] = OP_I32;
                } else {
                    fixup_type = FIX_RELOFF16;
                    Code->info.opnd_type[Opnd_Count] = OP_I16;
                }
#endif
                break;
            case MT_NEAR:
                fixup_option = OPTJ_EXPLICIT;
                if( Code->use32 ) {
                    fixup_type = FIX_RELOFF32;
                    Code->info.opnd_type[Opnd_Count] = OP_I32;
                } else {
                    fixup_type = FIX_RELOFF16;
                    Code->info.opnd_type[Opnd_Count] = OP_I16;
                }
                break;
            case MT_DWORD:
            case MT_WORD:
#if defined( _STANDALONE_ )
            case MT_SDWORD:
            case MT_SWORD:
#endif
                *flags = INDIRECT_JUMP;
                return( RC_OK );
#if defined( _STANDALONE_ )
            case MT_SBYTE:
#endif
            case MT_BYTE:
            case MT_FWORD:
            case MT_QWORD:
            case MT_TBYTE:
            case MT_OWORD:
                AsmError( INVALID_SIZE );
                return( RC_ERROR );
            }
//            check_assume( sym, PREFIX_EMPTY );
            break;
        case T_JCXZ:
        case T_JECXZ:
            // JCXZ and JECXZ always require SHORT label
        case T_LOOP:
        case T_LOOPE:
        case T_LOOPNE:
        case T_LOOPNZ:
        case T_LOOPZ:
        case T_LOOPD:
        case T_LOOPED:
        case T_LOOPNED:
        case T_LOOPNZD:
        case T_LOOPZD:
        case T_LOOPW:
        case T_LOOPEW:
        case T_LOOPNEW:
        case T_LOOPNZW:
        case T_LOOPZW:
#if defined( _STANDALONE_ )
            if( ( Code->mem_type != MT_EMPTY ) &&
                ( Code->mem_type != MT_SHORT ) &&
                ( (Options.mode & MODE_IDEAL) == 0 ) ) {
#else
            if( ( Code->mem_type != MT_EMPTY ) &&
                ( Code->mem_type != MT_SHORT ) ) {
#endif
                AsmError( ONLY_SHORT_DISPLACEMENT_IS_ALLOWED );
                return( RC_ERROR );
            }
            Code->info.opnd_type[Opnd_Count] = OP_I8;
            fixup_option = OPTJ_EXPLICIT;
            fixup_type = FIX_RELOFF8;
            break;
        default:
            if( (Code->info.cpu&P_CPU_MASK) >= P_386 ) {
                switch( Code->mem_type ) {
                case MT_SHORT:
                    fixup_option = OPTJ_EXPLICIT;
                    fixup_type = FIX_RELOFF8;
                    Code->info.opnd_type[Opnd_Count] = OP_I8;
                    break;
                case MT_EMPTY:
                    // forward reference
                    // inline assembler default distance is near
                    // stand-alone assembler default distance is short
#if defined( _STANDALONE_ )
                    fixup_option = OPTJ_JXX;
                    fixup_type = FIX_RELOFF8;
                    Code->info.opnd_type[Opnd_Count] = OP_I8;
                    break;
#endif
                case MT_NEAR:
                    fixup_option = OPTJ_EXPLICIT;
                    if( Code->use32 ) {
                        fixup_type = FIX_RELOFF32;
                        Code->info.opnd_type[Opnd_Count] = OP_I32;
                    } else {
                        fixup_type = FIX_RELOFF16;
                        Code->info.opnd_type[Opnd_Count] = OP_I16;
                    }
                    break;
                case MT_FAR:
#if defined( _STANDALONE_ )
                    jumpExtend( 1 );
                    *flags = SCRAP_INSTRUCTION;
                    return( RC_OK );
#endif
                default:
                    AsmError( ONLY_SHORT_AND_NEAR_DISPLACEMENT_IS_ALLOWED );
                    return( RC_ERROR );
                }
            } else {
                // the only mode in 8086, 80186, 80286 is
                // Jxx SHORT
                switch( Code->mem_type ) {
                case MT_EMPTY:
#if defined( _STANDALONE_ )
                    fixup_option = OPTJ_EXTEND;
                    fixup_type = FIX_RELOFF8;
                    Code->info.opnd_type[Opnd_Count] = OP_I8;
                    break;
#endif
                case MT_SHORT:
                    fixup_option = OPTJ_EXPLICIT;
                    fixup_type = FIX_RELOFF8;
                    Code->info.opnd_type[Opnd_Count] = OP_I8;
                    break;
                default:
                    AsmError( ONLY_SHORT_DISPLACEMENT_IS_ALLOWED );
                    return( RC_ERROR );
                }
            }
        }
        AddFixup( sym, fixup_type, fixup_option );
        break;
    default: /* SYM_STACK */
        AsmError( NO_JUMP_TO_AUTO );
        return( RC_ERROR );
    }
    return( RC_OK );
}

bool ptr_operator( memtype mem_type, bool fix_mem_type )
/******************************************************/
/*
  determine what should be done with SHORT, NEAR, FAR, BYTE, WORD, DWORD, PTR
  operator;
*/
{
    /* new idea:
     * when we get a near/far/dword/etc, just set distance / mem_type
     * operator will be called again with PTR, then we set the opsiz, etc.
     */

    if( Code->info.token == T_LEA )
        return( RC_OK );
    if( Code->info.token == T_SMSW )
        return( RC_OK );
    if( mem_type == MT_PTR ) {
        /* finish deciding what type to make the inst NOW
         * ie: decide size overrides etc.
         */
        if( Code->use32 && MEM_TYPE( Code->mem_type, WORD ) ) {
            // if we are in use32 mode, we have to add OPSIZ prefix for
            // most of the 386 instructions ( except MOVSX and MOVZX )
            // when we find WORD PTR

            if( !IS_BRANCH( Code->info.token ) ) {
                if( Code->info.opnd_type[OPND1] == OP_MMX ) {
                /* JBS 2001/02/19
                no WORD operands for MMX instructions, only 64-bit or 128-bit
                so no WORD override needed
                    */
                } else {
                    switch( Code->info.token ) {
                    case T_MOVSX:
                    case T_MOVZX:
                        break;
                    default:
                        SET_OPSIZ_ON( Code );
                        break;
                    }
                }
            }

        } else if( !Code->use32 && MEM_TYPE( Code->mem_type, DWORD ) ) {

            /* if we are not in use32 mode, we have to add OPSIZ
             * when we find DWORD PTR
             * unless we have a LXS ins.
             * which moves a DWORD ptr into SR:word reg
             * fixme  - can this be done by breaking up the LXS instructions in
             *          asmins.h, and then putting F_32 or F_16 to append
             *      opsize bytes when necessary ?
             */
            if( !IS_BRANCH( Code->info.token ) ) {

                if( Code->info.opnd_type[OPND1] == OP_MMX ) {
                    /* JBS 2001/02/19
                       no WORD operands for MMX instructions, only 64-bit or 128-bit
                       so no DWORD override needed
                     */
                } else {
                    switch( Code->info.token ) {
                    case T_LDS:
                    case T_LES:
                    case T_LFS:
                    case T_LGS:
                    case T_LSS:
                        /* in these cases, opsize does NOT need to be changed  */
                        break;
                    default:
                        // OPSIZ prefix
                        SET_OPSIZ_ON( Code );
                    }
                }
            }
        }
    } else {
        if( ( mem_type != MT_EMPTY ) && !Code->mem_type_fixed ) {
#if defined( _STANDALONE_ )
            if( mem_type != MT_STRUCT ) {
#endif
                Code->mem_type = mem_type;
                if( fix_mem_type ) {
                    Code->mem_type_fixed = true;
                    if( mem_type == MT_FAR ) {
                        if( Code->info.token == T_CALL ) {
                            Code->info.token = T_CALLF;
                        } else if( Code->info.token == T_JMP ) {
                            Code->info.token = T_JMPF;
                        }
                    }
                }

#if defined( _STANDALONE_ )
            }
#endif
        }
    }
    return( RC_OK );
}
コード例 #9
0
int directive( int i, long direct )
/* Handle all directives */
{
    int         ret;

    /* no expansion on the following */
    switch( direct ) {
    case T_MASM:
        Options.mode &= ~MODE_IDEAL;
        return( NOT_ERROR );
    case T_IDEAL:
        Options.mode |= MODE_IDEAL;
        return( NOT_ERROR );
    case T_DOT_286C:
        direct = T_DOT_286;
    case T_DOT_8086:
    case T_DOT_186:
    case T_DOT_286:
    case T_DOT_286P:
    case T_DOT_386:
    case T_DOT_386P:
    case T_DOT_486:
    case T_DOT_486P:
    case T_DOT_586:
    case T_DOT_586P:
    case T_DOT_686:
    case T_DOT_686P:
    case T_DOT_8087:
    case T_DOT_287:
    case T_DOT_387:
    case T_DOT_NO87:
    case T_DOT_K3D:
    case T_DOT_MMX:
    case T_DOT_XMM:
    case T_DOT_XMM2:
    case T_DOT_XMM3:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        } else {
            ret = cpu_directive(direct);
            if( Parse_Pass != PASS_1 )
                ret = NOT_ERROR;
            return( ret );
        }
    case T_P286N:
        direct = T_P286;
    case T_P8086:
    case T_P186:
    case T_P286:
    case T_P286P:
    case T_P386:
    case T_P386P:
    case T_P486:
    case T_P486P:
    case T_P586:
    case T_P586P:
    case T_P686:
    case T_P686P:
    case T_P8087:
    case T_P287:
    case T_P387:
    case T_PK3D:
    case T_PMMX:
    case T_PXMM:
    case T_PXMM2:
    case T_PXMM3:
        ret = cpu_directive(direct);
        if( Parse_Pass != PASS_1 )
            ret = NOT_ERROR;
        return( ret );
    case T_DOT_DOSSEG:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_DOSSEG:
        Globals.dosseg = TRUE;
        return( NOT_ERROR );
    case T_PUBLIC:
        /* special case - expanded inside iff it is an EQU to a symbol */
        return( Parse_Pass == PASS_1 ? PubDef(i+1) : NOT_ERROR );
    case T_ELSE:
    case T_ELSEIF:
    case T_ELSEIF1:
    case T_ELSEIF2:
    case T_ELSEIFB:
    case T_ELSEIFDEF:
    case T_ELSEIFE:
    case T_ELSEIFNB:
    case T_ELSEIFNDEF:
    case T_ELSEIFDIF:
    case T_ELSEIFDIFI:
    case T_ELSEIFIDN:
    case T_ELSEIFIDNI:
    case T_ENDIF:
    case T_IF:
    case T_IF1:
    case T_IF2:
    case T_IFB:
    case T_IFDEF:
    case T_IFE:
    case T_IFNB:
    case T_IFNDEF:
    case T_IFDIF:
    case T_IFDIFI:
    case T_IFIDN:
    case T_IFIDNI:
        return( conditional_assembly_directive( i ) );
    case T_DOT_ERR:
    case T_DOT_ERRB:
    case T_DOT_ERRDEF:
    case T_DOT_ERRDIF:
    case T_DOT_ERRDIFI:
    case T_DOT_ERRE:
    case T_DOT_ERRIDN:
    case T_DOT_ERRIDNI:
    case T_DOT_ERRNB:
    case T_DOT_ERRNDEF:
    case T_DOT_ERRNZ:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ERR:
    case T_ERRIFB:
    case T_ERRIFDEF:
    case T_ERRIFDIF:
    case T_ERRIFDIFI:
    case T_ERRIFE:
    case T_ERRIFIDN:
    case T_ERRIFIDNI:
    case T_ERRIFNDEF:
        return( conditional_error_directive( i ) );
    case T_ENDS:
        if( Definition.struct_depth != 0 )
            return( StructDef( i ) );
        // else fall through to T_SEGMENT
    case T_SEGMENT:
        return( Parse_Pass == PASS_1 ? SegDef(i) : SetCurrSeg(i) );
    case T_GROUP:
        return( Parse_Pass == PASS_1 ? GrpDef(i) : NOT_ERROR );
    case T_PROC:
        return( ProcDef( i, TRUE ) );
    case T_ENDP:
        return( ProcEnd(i) );
    case T_ENUM:
        return( EnumDef( i ) );
    case T_DOT_CODE:
    case T_DOT_STACK:
    case T_DOT_DATA:
    case T_DOT_DATA_UN:
    case T_DOT_FARDATA:
    case T_DOT_FARDATA_UN:
    case T_DOT_CONST:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CODESEG:
    case T_STACK:
    case T_DATASEG:
    case T_UDATASEG:
    case T_FARDATA:
    case T_UFARDATA:
    case T_CONST:
        return( SimSeg(i) );
    case T_WARN:
    case T_NOWARN:
        return( NOT_ERROR ); /* Not implemented yet */
    case T_DOT_ALPHA:
    case T_DOT_SEQ:
    case T_DOT_LIST:
    case T_DOT_LISTALL:
    case T_DOT_LISTIF:
    case T_DOT_LISTMACRO:
    case T_DOT_LISTMACROALL:
    case T_DOT_NOLIST:
    case T_DOT_XLIST:
    case T_DOT_TFCOND:
    case T_DOT_SFCOND:
    case T_DOT_LFCOND:
    case T_DOT_CREF:
    case T_DOT_XCREF:
    case T_DOT_NOCREF:
    case T_DOT_SALL:
    case T_PAGE:
    case T_TITLE:
    case T_SUBTITLE:
    case T_SUBTTL:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
        AsmWarn( 4, IGNORING_DIRECTIVE );
        return( NOT_ERROR );
    case T_DOT_BREAK:
    case T_DOT_CONTINUE:
    case T_DOT_ELSE:
    case T_DOT_ENDIF:
    case T_DOT_ENDW:
    case T_DOT_IF:
    case T_DOT_RADIX:
    case T_DOT_REPEAT:
    case T_DOT_UNTIL:
    case T_DOT_WHILE:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ECHO:
    case T_HIGH:
    case T_HIGHWORD:
    case T_LOW:
    case T_LOWWORD:
    case T_ADDR:
    case T_BOUND:
    case T_CASEMAP:
    case T_INVOKE:
    case T_LROFFSET:
    case T_OPATTR:
    case T_OPTION:
    case T_POPCONTEXT:
    case T_PUSHCONTEXT:
    case T_PROTO:
    case T_THIS:
    case T_WIDTH:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CATSTR:
    case T_MASK:
    case T_PURGE:
    case T_RECORD:
    case T_TYPEDEF:
    case T_UNION:
        AsmError( NOT_SUPPORTED );
        return( ERROR );
    case T_ORG:
        ExpandTheWorld( 0, FALSE, TRUE );
        break;
    case T_TEXTEQU:     /* TEXTEQU */
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_EQU2:        /* = */
    case T_EQU:         /* EQU */
        /* expand any constants and simplify any expressions */
        ExpandTheConstant( 0, FALSE, TRUE );
        break;
    case T_NAME:        /* no expand parameters */
        break;
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_STARTUPCODE:
    case T_EXITCODE:
    default:
        /* expand any constants in all other directives */
        ExpandAllConsts( 0, FALSE );
        break;
    }

    switch( direct ) {
    case T_ALIAS:
        if( Parse_Pass == PASS_1 )
            return( AddAlias( i ) );
        return( NOT_ERROR );
    case T_EXTERN:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_EXTRN:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, FALSE ) : NOT_ERROR );
    case T_COMM:
        return( Parse_Pass == PASS_1 ? CommDef(i+1) : NOT_ERROR );
    case T_EXTERNDEF:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_GLOBAL:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, TRUE ) : NOT_ERROR );
    case T_DOT_MODEL:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_MODEL:
        return( Model(i) );
    case T_INCLUDE:
        return( Include(i+1) );
    case T_INCLUDELIB:
        return( Parse_Pass == PASS_1 ? IncludeLib(i+1) : NOT_ERROR );
    case T_ASSUME:
        return( SetAssume(i) );
    case T_END:
        return( ModuleEnd(Token_Count) );
    case T_EQU:
        return( DefineConstant( i-1, FALSE, FALSE ) );
    case T_EQU2:
        return( DefineConstant( i-1, TRUE, FALSE ) );
    case T_TEXTEQU:
        return( DefineConstant( i-1, TRUE, TRUE ) );
    case T_MACRO:
        return( MacroDef(i, FALSE ) );
    case T_ENDM:
        return( MacroEnd( FALSE ) );
    case T_EXITM:
        return( MacroEnd( TRUE ) );
    case T_ARG:
        return( Parse_Pass == PASS_1 ? ArgDef(i) : NOT_ERROR );
    case T_USES:
        return( Parse_Pass == PASS_1 ? UsesDef(i) : NOT_ERROR );
    case T_LOCAL:
        return( Parse_Pass == PASS_1 ? LocalDef(i) : NOT_ERROR );
    case T_COMMENT:
        if( Options.mode & MODE_IDEAL )
            break;
        return( Comment( START_COMMENT, i ) );
    case T_STRUCT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_STRUC:
        return( StructDef( i ) );
    case T_NAME:
        return( Parse_Pass == PASS_1 ? NameDirective(i) : NOT_ERROR );
    case T_LABEL:
        return( LabelDirective( i ) );
    case T_ORG:
        return( OrgDirective( i ) );
    case T_ALIGN:
    case T_EVEN:
        return( AlignDirective( direct, i ) );
    case T_FOR:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRP:
        return( ForDirective ( i+1, IRP_WORD ) );
    case T_FORC:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRPC:
        return( ForDirective ( i+1, IRP_CHAR ) );
    case T_REPEAT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_REPT:
        return( ForDirective ( i+1, IRP_REPEAT ) );
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
    case T_STARTUPCODE:
    case T_EXITCODE:
        return( Startup ( i ) );
    case T_LOCALS:
    case T_NOLOCALS:
        return( Locals( i ) );
    }
    AsmError( UNKNOWN_DIRECTIVE );
    return( ERROR );
}
コード例 #10
0
ファイル: hll.c プロジェクト: OS2World/DEV-ASM-UTIL-JWasm
ret_code HllEndDef( int i )
/*************************/
{
    //struct asm_sym      *sym;
    struct hll_list     *hll;
    int                 cmd = AsmBuffer[i]->value;
    char                buffer[MAX_ID_LEN+1+64];
    
    DebugMsg(("HllEndDef(%s) enter\n", AsmBuffer[i]->string_ptr ));

    if ( HllStack == NULL ) {
        DebugMsg(("HllEndDef: hll stack is empty\n"));
        AsmError( DIRECTIVE_MUST_BE_IN_CONTROL_BLOCK );
        return( ERROR );
    }

    hll = HllStack;
    HllStack = hll->next;


    PushLineQueue();

    switch (cmd) {
    case T_DOT_ENDIF:
        if ( hll->cmd != HLL_IF ) {
            DebugMsg(("HllEndDef no .IF on the hll stack\n"));
            AsmErr( BLOCK_NESTING_ERROR, AsmBuffer[i]->string_ptr );
            return( ERROR );
        }
        /* if a test label isn't created yet, create it */
        if ( hll->symtest ) {
            MakeLabel( buffer, hll->symtest );
            AddLineQueue( buffer );
        }
        /* create the exit label if it exists */
        if ( hll->symexit ) {
            MakeLabel( buffer, hll->symexit );
            AddLineQueue( buffer );
        }
        i++;
        break;
    case T_DOT_ENDW:
        if ( hll->cmd != HLL_WHILE ) {
            DebugMsg(("HllEndDef no .WHILE on the hll stack\n"));
            AsmErr( BLOCK_NESTING_ERROR, AsmBuffer[i]->string_ptr );
            return( ERROR );
        }
        /* create test label  */
        if ( hll->symtest ) {
            MakeLabel( buffer, hll->symtest );
            DebugMsg(("HllEndDef: created: %s\n", buffer));
            AddLineQueue( buffer );
        }
        HllPushTestLines( hll );

        MakeLabel( buffer, hll->symexit );
        AddLineQueue( buffer );
        i++;
        break;
    case T_DOT_UNTILCXZ:
        if ( hll->cmd != HLL_REPEAT ) {
            DebugMsg(("HllEndDef no .REPEAT on the hll stack\n"));
            AsmErr( BLOCK_NESTING_ERROR, AsmBuffer[i]->string_ptr );
            return( ERROR );
        }
        MakeLabel( buffer, hll->symtest );
        AddLineQueue( buffer );

        i++;
        /* read in optional (simple) expression */
        if ( AsmBuffer[i]->token != T_FINAL ) {
            if ( ERROR == EvaluateHllExpression( hll, &i, LABELFIRST, FALSE ) ) {
                return( ERROR );
            }
            if ( HllCheckTestLines(hll) == ERROR ) {
                AsmError( EXPR_TOO_COMPLEX_FOR_UNTILCXZ );
                return( ERROR );
            }
            /* write condition lines */
            HllPushTestLines( hll );
        } else {
            sprintf( buffer, " loop %s", hll->symfirst );
            AddLineQueue( buffer );
        }
        MakeLabel( buffer, hll->symexit );
        AddLineQueue( buffer );
        break;
    case T_DOT_UNTIL:
        if ( hll->cmd != HLL_REPEAT ) {
            DebugMsg(("HllEndDef no .REPEAT on the hll stack\n"));
            AsmErr( BLOCK_NESTING_ERROR, AsmBuffer[i]->string_ptr );
            return( ERROR );
        }
        MakeLabel( buffer, hll->symtest );
        AddLineQueue( buffer );

        i++;
        /* read in (optional) expression */
        /* if expression is missing, just generate nothing */
        if ( AsmBuffer[i]->token != T_FINAL ) {
            if ( ERROR == EvaluateHllExpression( hll, &i, LABELFIRST, FALSE ) ) {
                return( ERROR );
            }
            /* write condition lines */
            HllPushTestLines( hll );
        }
#if 0
        sprintf( buffer, " jmp %s", hll->symfirst );
        AddLineQueue( buffer );
#endif

        MakeLabel( buffer, hll->symexit );
        AddLineQueue( buffer );
        break;
    }

    AsmFree( hll->symfirst );
    AsmFree( hll->symtest );
    AsmFree( hll->symexit );
    AsmFree( hll->condlines );
    AsmFree( hll );

    if ( AsmBuffer[i]->token != T_FINAL ) {
        AsmErr( SYNTAX_ERROR_EX, AsmBuffer[i]->string_ptr );
        return( ERROR );
    }

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_DIRECTIVE, GetCurrOffset(), NULL );

    if ( line_queue )
        RunLineQueue();

    return( NOT_ERROR );
}
コード例 #11
0
ファイル: hll.c プロジェクト: OS2World/DEV-ASM-UTIL-JWasm
ret_code HllStartDef( int i )
/***************************/
{
    struct hll_list      *hll;
    int                  cmd = AsmBuffer[i]->value;
    char                 buffer[MAX_ID_LEN+1+64];

    DebugMsg(("HllStartDef(%u [=%s]) enter\n", i, AsmBuffer[i]->string_ptr ));

#if FASTPASS
    /* make sure the directive is stored */
    if ( StoreState == FALSE && Parse_Pass == PASS_1 ) {
        SaveState();
    }
#endif

    switch (cmd) {
    case T_DOT_REPEAT:
        if ( AsmBuffer[i+1]->token != T_FINAL ) {
            DebugMsg(("HllStartDef: unexpected tokens behind .REPEAT\n" ));
            AsmError( SYNTAX_ERROR );
            return( ERROR );
        }
        break;
    case T_DOT_IF:
    case T_DOT_WHILE:
#if 0 /* Masm allows a missing expression! */
        if ( AsmBuffer[i+1]->token == T_FINAL ) {
            AsmError( SYNTAX_ERROR );
            return( ERROR );
        }
#endif
        break;
    }
    hll = AsmAlloc( sizeof(hll_list) );

    hll->cmd = HLL_UNDEF;

    /* create labels which are always needed */
    /* for .IF -.ENDIF without .ELSE no symexit label is needed. */

    hll->symfirst = NULL;
    hll->symexit = NULL;
    hll->symtest = MakeAnonymousLabel();

    hll->condlines = NULL;

    // structure for .IF .ELSE .ENDIF
    //    cond jump to symtest
    //    ...
    //    jmp symexit
    //  symtest:
    //    ...
    //  symexit:

    // structure for .IF .ELSEIF
    //    cond jump to symtest
    //    ...
    //    jmp symexit
    //  symtest:
    //    cond jump to (new) symtest
    //    ...
    //    jmp symexit
    //  symtest:
    //    ...

    // structure for .WHILE and .REPEAT:
    //   jmp symtest (for .WHILE only)
    // symfirst:
    //   ...
    // symtest: (jumped to by .continue)
    //   test end condition, cond jump to symfirst
    // symexit: (jumped to by .break)

    PushLineQueue();

    switch (cmd) {
    case T_DOT_IF:
        hll->cmd = HLL_IF;
        /* get the C-style expression, convert to ASM code lines */
        i++;
        if ( ERROR == EvaluateHllExpression( hll, &i, LABELTEST, FALSE ) ) {
            return( ERROR );
        }
        HllPushTestLines( hll );
#if 1
        /* if no lines have been created, the symtest label isn't needed */
        if ( line_queue == NULL ) {
            AsmFree( hll->symtest );
            hll->symtest = NULL;
        }
#endif
        break;
    case T_DOT_WHILE:
    case T_DOT_REPEAT:
        /* create the label to loop start */
        hll->symfirst = MakeAnonymousLabel();
        hll->symexit = MakeAnonymousLabel();
        if ( cmd == T_DOT_WHILE ) {
            i++;
            hll->cmd = HLL_WHILE;
            if ( AsmBuffer[i]->token != T_FINAL ) {
                if ( ERROR == EvaluateHllExpression( hll, &i, LABELFIRST, TRUE ) ) {
                    return( ERROR );
                }
            } else
                hll->condlines = "";
            /* create a jump to second label */
            /* optimisation: if second label is just a jump, dont jump! */
            if ( hll->condlines && _memicmp(hll->condlines, "jmp", 3) ) {
                sprintf( buffer, " jmp %s", hll->symtest );
                AddLineQueue( buffer );
            } else {
                AsmFree( hll->symtest );
                hll->symtest = NULL;
            }
        } else {
            i++;
            hll->cmd = HLL_REPEAT;
        }
        MakeLabel( buffer, hll->symfirst );
        AddLineQueue( buffer );
        break;
    }
    if ( AsmBuffer[i]->token != T_FINAL ) {
        DebugMsg(("HllStartDef: unexpected token %u [%s]\n", AsmBuffer[i]->token, AsmBuffer[i]->string_ptr ));
        AsmErr( SYNTAX_ERROR_EX, AsmBuffer[i]->string_ptr );
        return( ERROR );
    }
    hll->next = HllStack;
    HllStack = hll;

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_DIRECTIVE, GetCurrOffset(), NULL );

    if ( line_queue ) /* might be NULL! (".if 1") */
        RunLineQueue();

    return( NOT_ERROR );
}
コード例 #12
0
ファイル: hll.c プロジェクト: OS2World/DEV-ASM-UTIL-JWasm
static ret_code GetSimpleExpression( hll_list * hll, int *i, int ilabel, bool is_true, char * buffer, char **jmp, expr_list *opndx )
/**********************************************************************************************************************************/
{
    //expr_list opndx;
    expr_list op2;
    c_bop op;
    //int size;
    //int end_tok;
    int op1_pos;
    int op1_end;
    int op2_pos;
    int op2_end;
    char *label;
    bool issigned;

    DebugMsg(("GetSimpleExpression(buffer=%s) enter\n", buffer ));

    while ( AsmBuffer[*i]->string_ptr[0] == '!' && AsmBuffer[*i]->string_ptr[1] == '\0' ) {
        GetCOp(i);
        is_true = 1 - is_true;
    }

    op1_pos = *i;
    /* the problem with '()' is that is might enclose just a standard Masm
     * expression or a "hll" expression. The first case is to be handled 
     * entirely by the expression evaluator, while the latter case is to be
     * handled HERE!
     */
    if ( AsmBuffer[*i]->token == T_OP_BRACKET ) {
        int brcnt;
        int j;
        for ( brcnt = 1, j = *i + 1; AsmBuffer[j]->token != T_FINAL; j++ ) {
            if ( AsmBuffer[j]->token == T_OP_BRACKET )
                brcnt++;
            else if ( AsmBuffer[j]->token == T_CL_BRACKET ) {
                brcnt--;
                if ( brcnt == 0 ) /* a standard Masm expression? */
                    break;
            } else if ( ( GetCOp( &j )) != COP_NONE )
                break;
        }
        if ( brcnt ) {
            (*i)++;
            DebugMsg(("GetSimpleExpression: calling GetExpression, i=%u\n", *i));
            if ( ERROR == GetExpression( hll, i, ilabel, is_true, buffer, jmp, opndx ) )
                return( ERROR );
            DebugMsg(("return from GetExpression, i=%u\n", *i));

            if ( AsmBuffer[*i]->token != T_CL_BRACKET ) {
                //if ((AsmBuffer[*i]->token == T_FINAL) || (AsmBuffer[*i]->token == T_CL_BRACKET))
                DebugMsg(( "GetSimpleExpression: expected ')', found: %s\n", AsmBuffer[*i]->string_ptr ));
                AsmError( SYNTAX_ERROR_IN_CONTROL_FLOW_DIRECTIVE );
                return( ERROR );
            }
            (*i)++;
            return( NOT_ERROR );
        }
    }

    if ( ERROR == GetToken( hll, i, is_true, opndx ) )
        return ( ERROR );

    op1_end = *i;

    op = GetCOp( i );

    if ( op == COP_AND || op == COP_OR ) {
        *i = op1_end;
        if ( opndx->kind == EXPR_EMPTY )
            return( NOT_ERROR );
        op = COP_NONE;
    }

    label = GetLabel( hll, ilabel );

    DebugMsg(("GetSimpleExpression: EvalOperand ok, kind=%X, i=%u\n", opndx->kind, *i));

    if ( opndx->kind == EXPR_EMPTY ) {
        /* no valid ASM expression detected. check for some special ops */
        /* COP_ZERO, COP_CARRY, COP_SIGN, COP_PARITY, COP_OVERFLOW */
        if ( op >= COP_ZERO ) {
            //char t;
            char * p;
            //char * s;
            p = buffer;
            *jmp = p;
            *p++ = 'j';
            if ( is_true == FALSE )
                *p++ = 'n';

            switch ( op ) {
            case COP_CARRY:
                *p++ = 'c';
                break;
            case COP_ZERO:
                *p++ = 'z';
                break;
            case COP_SIGN:
                *p++ = 's';
                break;
            case COP_PARITY:
                *p++ = 'p';
                break;
            case COP_OVERFLOW:
                *p++ = 'o';
                break;
            }
            *p++ = ' ';
            if ( is_true == TRUE )
                *p++ = ' ';
            strcpy( p, label );
            goto done;
        }
        if ( hll->condlines )
            return( NOT_ERROR );
        else {
            AsmError( SYNTAX_ERROR_IN_CONTROL_FLOW_DIRECTIVE );
            return( NOT_ERROR );
        }
    }

    if ( ( opndx->kind != EXPR_CONST ) && ( opndx->kind != EXPR_ADDR ) && ( opndx->kind != EXPR_REG ) )
        return( ERROR );

    op2_pos = *i;

    if ( op != COP_NONE ) {
        if ( ERROR == GetToken( hll, i, is_true, &op2 ) ) {
            return( ERROR );
        }
        DebugMsg(("GetSimpleExpression: EvalOperand 2 ok, type=%X, i=%u\n", op2.type, *i));
        if ( ( op2.kind != EXPR_CONST ) && ( op2.kind != EXPR_ADDR ) && ( op2.kind != EXPR_REG ) ) {
            DebugMsg(("GetSimpleExpression: syntax error, op2.kind=%u\n", op2.kind ));
            AsmError( SYNTAX_ERROR );
            return( ERROR );
        }
    }
    op2_end = *i;

    /* now generate ASM code for expression */

    buffer[0] = 0;
    if ( ( op == COP_EQ ) ||
        ( op == COP_NE ) ||
        ( op == COP_GT ) ||
        ( op == COP_LT ) ||
        ( op == COP_GE ) ||
        ( op == COP_LE ) ) {
        char * p;

        /* optimisation: generate 'or EAX,EAX' instead of 'cmp EAX,0' */
        if ( Options.masm_compat_gencode &&
            ( op == COP_EQ || op == COP_NE ) &&
            opndx->kind == EXPR_REG &&
            opndx->indirect == FALSE &&
            op2.kind == EXPR_CONST &&
            op2.value == 0 ) {
            strcat( buffer," or " );
            RenderOpnd( opndx, buffer, op1_pos, op1_end );
            strcat( buffer, ", " );
            RenderOpnd( opndx, buffer, op1_pos, op1_end );
        } else {
            strcat( buffer," cmp " );
            RenderOpnd( opndx, buffer, op1_pos, op1_end );
            strcat( buffer, ", " );
            RenderOpnd( &op2, buffer, op2_pos, op2_end );
        }
        strcat( buffer, "\n" );

        p = buffer + strlen( buffer );
        *jmp = p;

        if (IS_SIGNED( opndx->mem_type ) || IS_SIGNED(op2.mem_type))
            issigned = TRUE;
        else
            issigned = FALSE;

        switch ( op ) {
        case COP_EQ:
            if ( is_true )
                strcpy( p, "jz  " );
            else
                strcpy( p, "jnz " );
            break;
        case COP_NE:
            if ( is_true )
                strcpy( p, "jnz " );
            else
                strcpy( p, "jz  " );
            break;
        case COP_GT:
            if ( issigned == TRUE ) {
                if ( is_true )
                    strcpy( p, "jg  " );
                else
                    strcpy( p, "jle " );
            } else {
                if ( is_true )
                    strcpy( p, "ja  " );
                else
                    strcpy( p, "jbe " );
            }
            break;
        case COP_LT:
            if ( issigned == TRUE ) {
                if ( is_true )
                    strcpy( p, "jl  " );
                else
                    strcpy( p, "jge " );
            } else {
                if ( is_true )
                    strcpy( p, "jb  " );
                else
                    strcpy( p, "jae " );
            }
            break;
        case COP_GE:
            if ( issigned == TRUE ) {
                if ( is_true )
                    strcpy( p, "jge " );
                else
                    strcpy( p, "jl  " );
            } else {
                if ( is_true )
                    strcpy( p, "jae " );
                else
                    strcpy( p, "jb  " );
            }
            break;
        case COP_LE:
            if ( issigned == TRUE ) {
                if ( is_true )
                    strcpy( p, "jle " );
                else
                    strcpy( p, "jg  " );
            } else {
                if ( is_true )
                    strcpy( p, "jbe " );
                else
                    strcpy( p, "ja  " );
            }
            break;
        }
        strcat( p, label );

    } else if ( op == COP_ANDB ) {
        char * p;

        strcat( buffer," test " );
        RenderOpnd( opndx, buffer, op1_pos, op1_end );
        strcat( buffer, ", " );
        RenderOpnd( &op2, buffer, op2_pos, op2_end );
        strcat( buffer, "\n" );

        p = buffer + strlen( buffer );
        *jmp = p;

        if ( is_true )
            strcpy( p, "jne " );
        else
            strcpy( p, "je  " );

        strcat( p, label );

    } else if ( op == COP_NONE ) {
        char * p;

        switch ( opndx->kind ) {
        case EXPR_REG:
            if ( opndx->indirect == FALSE ) {
                strcat( buffer, "and " );
                RenderOpnd( opndx, buffer, op1_pos, op1_end );
                strcat( buffer, ", " );
                RenderOpnd( opndx, buffer, op1_pos, op1_end );
                strcat( buffer, "\n" );
                p = buffer + strlen( buffer );
                *jmp = p;
                if ( is_true )
                    strcpy( p, "jnz " );
                else
                    strcpy( p, "jz  " );
                strcat( p, label );
                break;
            }
        case EXPR_ADDR:
            strcat( buffer, "cmp " );
            RenderOpnd( opndx, buffer, op1_pos, op1_end );
            strcat( buffer, ", 0\n" );
            p = buffer + strlen( buffer );
            *jmp = p;
            if ( is_true )
                strcpy( p, "jnz " );  /* switched */
            else
                strcpy( p, "jz  " );
            strcat( buffer, label );
            break;
        case EXPR_CONST:
            if ( opndx->string != NULL ) {
                AsmError( SYNTAX_ERROR_IN_CONTROL_FLOW_DIRECTIVE );
                return ( ERROR );
            }
            *jmp = buffer;
            if ( is_true == TRUE )
                if ( opndx->value )
                    sprintf( buffer, "jmp %s", label );
                else
                    strcpy( buffer, " "); /* make sure there is a char */
            if ( is_true == FALSE )
                if ( opndx->value == 0 )
                    sprintf( buffer, "jmp %s", label );
                else
                    strcpy( buffer, " " ); /* make sure there is a char */
            break;
        }
    }
done:
    strcat( buffer, "\n" );

    return( NOT_ERROR );
}
コード例 #13
0
ファイル: hll.c プロジェクト: OS2World/DEV-ASM-UTIL-JWasm
ret_code HllExitDef( int i )
/**************************/
{
    //int                 level;
    //struct asm_sym      *sym;
    struct hll_list     *hll;
    char                *savedlines;
    hll_cmd             savedcmd;
    int                 cmd = AsmBuffer[i]->value;
    char                buffer[MAX_ID_LEN+1+64];

    DebugMsg(("HllExitDef(%s) enter\n", AsmBuffer[i]->string_ptr ));

    hll = HllStack;

    if ( hll == NULL ) {
        DebugMsg(("HllExitDef stack error\n"));
        AsmError( DIRECTIVE_MUST_BE_IN_CONTROL_BLOCK );
        return( ERROR );
    }

    PushLineQueue();

    switch (cmd) {
    case T_DOT_ELSE:
    case T_DOT_ELSEIF:
        if ( hll->cmd != HLL_IF ) {
            DebugMsg(("HllExitDef(%s): symtest=%X\n", AsmBuffer[i]->string_ptr, hll->symtest));
            AsmErr( BLOCK_NESTING_ERROR, AsmBuffer[i]->string_ptr );
            return( ERROR );
        }
        /* the "symexit" label is only needed if an .ELSE branch exists.
         That's why it is created delayed.
         */
        if ( hll->symexit == NULL)
            hll->symexit = MakeAnonymousLabel();

        sprintf( buffer," jmp %s", hll->symexit );
        AddLineQueue( buffer );
        if ( hll->symtest ) {
            MakeLabel( buffer, hll->symtest );
            AddLineQueue( buffer );
            AsmFree( hll->symtest );
            hll->symtest = NULL;
        }
        i++;
        if (cmd == T_DOT_ELSEIF) {
            /* create new symtest label */
            hll->symtest = MakeAnonymousLabel();
            if ( ERROR == EvaluateHllExpression( hll, &i, LABELTEST, FALSE ) ) {
                return( ERROR );
            }
            HllPushTestLines( hll );
        }
        break;
    case T_DOT_BREAK:
    case T_DOT_CONTINUE:
        for ( ; hll && hll->cmd == HLL_IF; hll = hll->next );
        if ( hll == NULL ) {
            AsmError( DIRECTIVE_MUST_BE_IN_CONTROL_BLOCK );
            return( ERROR );
        }
        /* .BREAK .IF ... or .CONTINUE .IF ? */
        i++;
        if ( AsmBuffer[i]->token != T_FINAL ) {
            if ( AsmBuffer[i]->token == T_DIRECTIVE && AsmBuffer[i]->value == T_DOT_IF ) {
                savedlines = hll->condlines;
                savedcmd = hll->cmd;
                hll->condlines = NULL;
                hll->cmd = HLL_BREAK;
                i++;
                if ( cmd == T_DOT_BREAK ) {
                    if ( ERROR == EvaluateHllExpression( hll, &i, LABELEXIT, TRUE ) ) {
                        return( ERROR );
                    }
                } else { /* T_DOT_CONTINUE */
                    if ( ERROR == EvaluateHllExpression( hll, &i, LABELTEST, TRUE ) ) {
                        return( ERROR );
                    }
                }
                HllPushTestLines( hll );
                AsmFree( hll->condlines );
                hll->condlines = savedlines;
                hll->cmd = savedcmd;
            }
        } else {
            if ( cmd == T_DOT_BREAK ) {
                sprintf( buffer," jmp %s", hll->symexit );
            } else {
                if ( hll->symtest )
                    sprintf( buffer," jmp %s", hll->symtest );
                else
                    sprintf( buffer," jmp %s", hll->symfirst );
            }
            AddLineQueue( buffer );
        }
        break;
    }
    if ( AsmBuffer[i]->token != T_FINAL ) {
        AsmErr( SYNTAX_ERROR_EX, AsmBuffer[i]->string_ptr );
        return( ERROR );
    }

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_DIRECTIVE, GetCurrOffset(), NULL );

    RunLineQueue();

    return( NOT_ERROR );
}