Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

q3asm.c File Reference

#include "cmdlib.h"
#include "mathlib.h"
#include "qfiles.h"
#include "opstrings.h"

Include dependency graph for q3asm.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  executableHeader_t
struct  segment_t
struct  sourceOps_t
struct  symbol_s

Defines

#define atoi(s)   strtoul(s,NULL,10)
#define MAX_ASM_FILES   256
#define MAX_IMAGE   0x400000
#define MAX_LINE_LENGTH   1024
#define NUM_SOURCE_OPS   ( sizeof( sourceOps ) / sizeof( sourceOps[0] ) )
#define ZERO_PAGE_SIZE   0

Typedefs

typedef symbol_s symbol_t

Enumerations

enum  opcode_t {
  OP_UNDEF, OP_IGNORE, OP_BREAK, OP_ENTER,
  OP_LEAVE, OP_CALL, OP_PUSH, OP_POP,
  OP_CONST, OP_LOCAL, OP_JUMP, OP_EQ,
  OP_NE, OP_LTI, OP_LEI, OP_GTI,
  OP_GEI, OP_LTU, OP_LEU, OP_GTU,
  OP_GEU, OP_EQF, OP_NEF, OP_LTF,
  OP_LEF, OP_GTF, OP_GEF, OP_LOAD1,
  OP_LOAD2, OP_LOAD4, OP_STORE1, OP_STORE2,
  OP_STORE4, OP_ARG, OP_BLOCK_COPY, OP_SEX8,
  OP_SEX16, OP_NEGI, OP_ADD, OP_SUB,
  OP_DIVI, OP_DIVU, OP_MODI, OP_MODU,
  OP_MULI, OP_MULU, OP_BAND, OP_BOR,
  OP_BXOR, OP_BCOM, OP_LSH, OP_RSHI,
  OP_RSHU, OP_NEGF, OP_ADDF, OP_SUBF,
  OP_DIVF, OP_MULF, OP_CVIF, OP_CVFI
}
enum  segmentName_t {
  CODESEG, DATASEG, LITSEG, BSSSEG,
  NUM_SEGMENTS
}

Functions

void Assemble (void)
void AssembleLine (void)
void CodeError (char *fmt,...)
void DefineSymbol (char *sym, int value)
void EmitByte (segment_t *seg, int v)
void EmitInt (segment_t *seg, int v)
char * ExtractLine (char *data)
void HackToSegment (segmentName_t seg)
int HashString (char *s)
void InitTables (void)
int LookupSymbol (char *sym)
int main (int argc, char **argv)
qboolean Parse (void)
int ParseExpression (void)
void ParseOptionFile (const char *filename)
int ParseValue (void)
void WriteMapFile (void)
void WriteVmFile (void)

Variables

char * asmFileNames [MAX_ASM_FILES]
char * asmFiles [MAX_ASM_FILES]
int currentArgOffset
int currentArgs
int currentFileIndex
int currentFileLine
char * currentFileName
int currentLocals
segment_tcurrentSegment
int errorCount
int instructionCount
symbol_tlastSymbol
char lineBuffer [MAX_LINE_LENGTH]
int lineParseOffset
int numAsmFiles
int numSymbols
int opcodesHash [NUM_SOURCE_OPS]
char outputFilename [MAX_OS_PATH]
int passNumber
segment_t segment [NUM_SEGMENTS]
sourceOps_t sourceOps []
int stackSize = 0x10000
symbol_tsymbols
char token [MAX_LINE_LENGTH]


Define Documentation

#define atoi  )     strtoul(s,NULL,10)
 

Definition at line 28 of file q3asm.c.

Referenced by AAS_AlwaysTriggered_r(), AAS_GetJumpPadInfo(), AAS_IntForBSPEpairKey(), AAS_LoadAASFile(), AAS_PositionBrush(), AAS_Reachability_Elevator(), AAS_Reachability_FuncBobbing(), AAS_Reachability_Teleport(), AAS_ValidEntity(), ArenaServers_Insert(), ASE_KeyGEOMOBJECT(), ASE_KeyMATERIAL_LIST(), ASE_KeyMESH(), ASE_KeyMESH_FACE_LIST(), ASE_KeyTFACE_LIST(), BotFirstClientInRankings(), BotFuncButtonActivateGoal(), BotFuncDoorActivateGoal(), BotGetActivateGoal(), BotIsFirstInRankings(), BotIsLastInRankings(), BotIsObserver(), BotLastClientInRankings(), BotNumActivePlayers(), BotNumTeamMates(), BotRandomOpponentName(), BotSameTeam(), BotSetBrushModelTypes(), BotSetupDeathmatchAI(), BotSortTeamMatesByBaseTravelTime(), BotTeam(), BotTeamOrders(), BotTeamplayReport(), BotTriggerMultipleActivateGoal(), BotVoiceChatCommand(), Brush_Parse(), BrushPrimit_Parse(), CG_ColorFromString(), CG_ConfigStringModified(), CG_DrawInformation(), CG_Init(), CG_NewClientInfo(), CG_NewParticleArea(), CG_ParseAnimationFile(), CG_ParseScores(), CG_ParseServerinfo(), CG_ParseTeamInfo(), CG_ParseWarmup(), CG_RegisterCvars(), CG_SetConfigValues(), CG_StartOrbit_f(), CG_TargetCommand_f(), CG_VoiceChat(), CG_Weapon_f(), CheckTeamVote(), CL_ConfigstringModified(), CL_ConnectionlessPacket(), CL_GlobalServers_f(), CL_PlayDemo_f(), CL_ServerInfoPacket(), CL_SetServerInfo(), CL_SystemInfoChanged(), ClientForString(), ClientNumberFromString(), ClientSpawn(), ClientUserinfoChanged(), Cmd_CallTeamVote_f(), Cmd_CallVote_f(), Cmd_GameCommand_f(), Cmd_TeamTask_f(), Cmd_Tell_f(), Cmd_VoiceTell_f(), Cmd_Wait_f(), Com_ParseInt(), ConnectEntities(), CopyAndSelect(), CopySelected(), CopyToMap(), Cvar_Get(), Cvar_Set2(), DefineSymbol(), Eclass_InitFromText(), FindBrushDlgProc(), FS_PureServerSetLoadedPaks(), FS_PureServerSetReferencedPaks(), G_InitBots(), G_InitWorldSession(), G_ParseField(), G_SpawnInt(), HL_LoadMapFromBSP(), IN_KeyDown(), IN_KeyUp(), InGame_MenuInit(), Int_Parse(), IntForKey(), LayerForShader(), LightMain(), LoadAlphaMap(), LoopCount(), main(), main_init(), MoveHold(), NET_StringToAdr(), idCameraFOV::parse(), idCameraEvent::parse(), ParseRawBrush(), ParseShaderFile(), ParseTerrain(), idCameraPosition::parseToken(), Patch_Parse(), Q1_LoadMapFromBSP(), Q2_ParseBSPEntity(), Q3_ParseBSPEntity(), RotateHold(), CPrefsDlg::SavePrefs(), ServerOptions_Start(), SetEntityOrigins(), SetSpawnFlags(), SidesDlgProc(), Sin_ParseBSPEntity(), StringToFilter(), SV_AuthorizeIpPacket(), SV_DirectConnect(), SV_GetPlayerByNum(), SV_MapRestart_f(), SV_NextDownload_f(), SV_SetBrushModel(), SV_UserinfoChanged(), SV_VerifyPaks_f(), Svcmd_AddBot_f(), TeamMain_MenuInit(), Terrain_Parse(), Terrain_ParseFace(), UI_AddBotsMenu_Init(), UI_BuildPlayerList(), UI_BuildServerDisplayList(), UI_CalcPostGameStats(), UI_CanShowTierVideo(), UI_CinematicsMenu_f(), UI_FeederItemText(), UI_GetArenaInfoByNumber(), UI_GetAwardLevel(), UI_GetBestScore(), UI_GetCurrentGame(), UI_LogAwardData(), UI_ParseAnimationFile(), UI_RemoveBotsMenu_GetBots(), UI_SetBestScore(), UI_ShowTierVideo(), UI_SPArena_Start(), UI_SPLevelMenu(), UI_SPLevelMenu_Init(), UI_SPLevelMenu_SetMenuItems(), UI_SPPostgameMenu_f(), UI_SPPostgameMenu_MenuDraw(), UI_TeamOrdersMenu_BuildBotList(), UI_TeamOrdersMenu_f(), UI_TierCompleted(), UniqueTargetName(), VisMain(), VLightMain(), and VSoundMain().

#define MAX_ASM_FILES   256
 

Definition at line 165 of file q3asm.c.

#define MAX_IMAGE   0x400000
 

Definition at line 136 of file q3asm.c.

#define MAX_LINE_LENGTH   1024
 

Definition at line 184 of file q3asm.c.

#define NUM_SOURCE_OPS   ( sizeof( sourceOps ) / sizeof( sourceOps[0] ) )
 

Definition at line 376 of file q3asm.c.

#define ZERO_PAGE_SIZE   0
 

Definition at line 33 of file q3asm.c.


Typedef Documentation

typedef struct symbol_s symbol_t
 


Enumeration Type Documentation

enum opcode_t
 

Enumeration values:
OP_UNDEF 
OP_IGNORE 
OP_BREAK 
OP_ENTER 
OP_LEAVE 
OP_CALL 
OP_PUSH 
OP_POP 
OP_CONST 
OP_LOCAL 
OP_JUMP 
OP_EQ 
OP_NE 
OP_LTI 
OP_LEI 
OP_GTI 
OP_GEI 
OP_LTU 
OP_LEU 
OP_GTU 
OP_GEU 
OP_EQF 
OP_NEF 
OP_LTF 
OP_LEF 
OP_GTF 
OP_GEF 
OP_LOAD1 
OP_LOAD2 
OP_LOAD4 
OP_STORE1 
OP_STORE2 
OP_STORE4 
OP_ARG 
OP_BLOCK_COPY 
OP_SEX8 
OP_SEX16 
OP_NEGI 
OP_ADD 
OP_SUB 
OP_DIVI 
OP_DIVU 
OP_MODI 
OP_MODU 
OP_MULI 
OP_MULU 
OP_BAND 
OP_BOR 
OP_BXOR 
OP_BCOM 
OP_LSH 
OP_RSHI 
OP_RSHU 
OP_NEGF 
OP_ADDF 
OP_SUBF 
OP_DIVF 
OP_MULF 
OP_CVIF 
OP_CVFI 

Definition at line 35 of file q3asm.c.

00035              {
00036     OP_UNDEF, 
00037 
00038     OP_IGNORE, 
00039 
00040     OP_BREAK, 
00041 
00042     OP_ENTER,
00043     OP_LEAVE,
00044     OP_CALL,
00045     OP_PUSH,
00046     OP_POP,
00047 
00048     OP_CONST,
00049     OP_LOCAL,
00050 
00051     OP_JUMP,
00052 
00053     //-------------------
00054 
00055     OP_EQ,
00056     OP_NE,
00057 
00058     OP_LTI,
00059     OP_LEI,
00060     OP_GTI,
00061     OP_GEI,
00062 
00063     OP_LTU,
00064     OP_LEU,
00065     OP_GTU,
00066     OP_GEU,
00067 
00068     OP_EQF,
00069     OP_NEF,
00070 
00071     OP_LTF,
00072     OP_LEF,
00073     OP_GTF,
00074     OP_GEF,
00075 
00076     //-------------------
00077 
00078     OP_LOAD1,
00079     OP_LOAD2,
00080     OP_LOAD4,
00081     OP_STORE1,
00082     OP_STORE2,
00083     OP_STORE4,              // *(stack[top-1]) = stack[yop
00084     OP_ARG,
00085     OP_BLOCK_COPY,
00086 
00087     //-------------------
00088 
00089     OP_SEX8,
00090     OP_SEX16,
00091 
00092     OP_NEGI,
00093     OP_ADD,
00094     OP_SUB,
00095     OP_DIVI,
00096     OP_DIVU,
00097     OP_MODI,
00098     OP_MODU,
00099     OP_MULI,
00100     OP_MULU,
00101 
00102     OP_BAND,
00103     OP_BOR,
00104     OP_BXOR,
00105     OP_BCOM,
00106 
00107     OP_LSH,
00108     OP_RSHI,
00109     OP_RSHU,
00110 
00111     OP_NEGF,
00112     OP_ADDF,
00113     OP_SUBF,
00114     OP_DIVF,
00115     OP_MULF,
00116 
00117     OP_CVIF,
00118     OP_CVFI
00119 } opcode_t;

enum segmentName_t
 

Enumeration values:
CODESEG 
DATASEG 
LITSEG 
BSSSEG 
NUM_SEGMENTS 

Definition at line 128 of file q3asm.c.

00128              {
00129     CODESEG,
00130     DATASEG,    // initialized 32 bit data, will be byte swapped
00131     LITSEG,     // strings
00132     BSSSEG,     // 0 filled
00133     NUM_SEGMENTS
00134 } segmentName_t;


Function Documentation

void Assemble void   ) 
 

Definition at line 1076 of file q3asm.c.

void AssembleLine void   ) 
 

Definition at line 722 of file q3asm.c.

References currentSegment, and segment.

00725                                    {
00726         currentSegment = &segment[BSSSEG];
00727         return;
00728     }
00729     if ( !strcmp( token, "data" ) ) {
00730         currentSegment = &segment[DATASEG];
00731         return;
00732     }
00733     if ( !strcmp( token, "lit" ) ) {
00734         currentSegment = &segment[LITSEG];
00735         return;
00736     }
00737     if ( !strcmp( token, "line" ) ) {
00738         return;
00739     }
00740     if ( !strcmp( token, "file" ) ) {
00741         return;
00742     }
00743 
00744     if ( !strcmp( token, "equ" ) ) {
00745         char    name[1024];
00746 
00747         Parse();
00748         strcpy( name, token );
00749         Parse();
00750         DefineSymbol( name, atoi(token) );
00751         return;
00752     }
00753 
00754     if ( !strcmp( token, "align" ) ) {
00755         v = ParseValue();
00756         currentSegment->imageUsed = (currentSegment->imageUsed + v - 1 ) & ~( v - 1 );
00757         return;
00758     }
00759 
00760     if ( !strcmp( token, "skip" ) ) {
00761         v = ParseValue();
00762         currentSegment->imageUsed += v;
00763         return;
00764     }
00765 
00766     if ( !strcmp( token, "byte" ) ) {
00767         v = ParseValue();
00768         v2 = ParseValue();
00769 
00770         if ( v == 1 ) {
00771             HackToSegment( LITSEG );
00772         } else if ( v == 4 ) {
00773             HackToSegment( DATASEG );
00774         } else if ( v == 2 ) {
00775             CodeError( "16 bit initialized data not supported" );
00776         }
00777 
00778         // emit little endien
00779         for ( i = 0 ; i < v ; i++ ) {
00780             EmitByte( currentSegment, v2 );
00781             v2 >>= 8;
00782         }
00783         return;
00784     }
00785 
00786     // code labels are emited as instruction counts, not byte offsets,
00787     // because the physical size of the code will change with
00788     // different run time compilers and we want to minimize the
00789     // size of the required translation table
00790     if ( !strncmp( token, "LABEL", 5 ) ) {
00791         Parse();
00792         if ( currentSegment == &segment[CODESEG] ) {
00793             DefineSymbol( token, instructionCount );
00794         } else {
00795             DefineSymbol( token, currentSegment->imageUsed );
00796         }
00797         return;
00798     }
00799 
00800     CodeError( "Unknown token: %s\n", token );
00801 }
00802 
00803 /*
00804 ==============
00805 InitTables
00806 ==============
00807 */
00808 void InitTables( void ) {
00809     int     i;
00810 
00811     for ( i = 0 ; i < NUM_SOURCE_OPS ; i++ ) {
00812         opcodesHash[i] = HashString( sourceOps[i].name );
00813     }
00814 }
00815 
00816 
00817 /*
00818 ==============
00819 WriteMapFile
00820 ==============
00821 */
00822 void WriteMapFile( void ) {
00823     FILE        *f;
00824     symbol_t    *s;
00825     char        imageName[MAX_OS_PATH];
00826     int         seg;
00827 
00828     strcpy( imageName, outputFilename );
00829     StripExtension( imageName );
00830     strcat( imageName, ".map" );
00831 
00832     printf( "Writing %s...\n", imageName );
00833     f = SafeOpenWrite( imageName );
00834     for ( seg = CODESEG ; seg <= BSSSEG ; seg++ ) {
00835         for ( s = symbols ; s ; s = s->next ) {
00836             if ( s->name[0] == '$' ) {
00837                 continue;   // skip locals
00838             }
00839             if ( &segment[seg] != s->segment ) {
00840                 continue;
00841             }
00842             fprintf( f, "%i %8x %s\n", seg, s->value, s->name );
00843         }
00844     }
00845     fclose( f );
00846 }
00847 
00848 /*
00849 ===============
00850 WriteVmFile
00851 ===============
00852 */
00853 void WriteVmFile( void ) {
00854     char    imageName[MAX_OS_PATH];
00855     vmHeader_t  header;
00856     FILE    *f;
00857 
00858     printf( "%i total errors\n", errorCount );
00859     strcpy( imageName, outputFilename );
00860     StripExtension( imageName );
00861     strcat( imageName, ".qvm" );
00862 
00863     remove( imageName );
00864 
00865     printf( "code segment: %7i\n", segment[CODESEG].imageUsed );
00866     printf( "data segment: %7i\n", segment[DATASEG].imageUsed );
00867     printf( "lit  segment: %7i\n", segment[LITSEG].imageUsed );
00868     printf( "bss  segment: %7i\n", segment[BSSSEG].imageUsed );
00869     printf( "instruction count: %i\n", instructionCount );
00870     if ( errorCount != 0 ) {
00871         printf( "Not writing a file due to errors\n" );
00872         return;
00873     }
00874 
00875     header.vmMagic = VM_MAGIC;
00876     header.instructionCount = instructionCount;
00877     header.codeOffset = sizeof( header );
00878     header.codeLength = segment[CODESEG].imageUsed;
00879     header.dataOffset = header.codeOffset + segment[CODESEG].imageUsed;
00880     header.dataLength = segment[DATASEG].imageUsed;
00881     header.litLength = segment[LITSEG].imageUsed;
00882     header.bssLength = segment[BSSSEG].imageUsed;
00883 
00884     printf( "Writing to %s\n", imageName );
00885 
00886     CreatePath( imageName );
00887     f = SafeOpenWrite( imageName );
00888     SafeWrite( f, &header, sizeof( header ) );
00889     SafeWrite( f, &segment[CODESEG].image, segment[CODESEG].imageUsed );
00890     SafeWrite( f, &segment[DATASEG].image, segment[DATASEG].imageUsed );
00891     SafeWrite( f, &segment[LITSEG].image, segment[LITSEG].imageUsed );
00892     fclose( f );
00893 }
00894 
00895 /*
00896 ===============
00897 Assemble
00898 ===============
00899 */
00900 void Assemble( void ) {
00901     int     i;
00902     char    filename[MAX_OS_PATH];
00903     char        *ptr;
00904 
00905     printf( "outputFilename: %s\n", outputFilename );
00906 
00907     for ( i = 0 ; i < numAsmFiles ; i++ ) {
00908         strcpy( filename, asmFileNames[ i ] );
00909         DefaultExtension( filename, ".asm" );
00910         LoadFile( filename, (void **)&asmFiles[i] );
00911     }
00912 
00913     // assemble
00914     for ( passNumber = 0 ; passNumber < 2 ; passNumber++ ) {
00915         segment[LITSEG].segmentBase = segment[DATASEG].imageUsed;
00916         segment[BSSSEG].segmentBase = segment[LITSEG].segmentBase + segment[LITSEG].imageUsed;
00917         for ( i = 0 ; i < NUM_SEGMENTS ; i++ ) {
00918             segment[i].imageUsed = 0;
00919         }
00920         segment[DATASEG].imageUsed = 4;     // skip the 0 byte, so NULL pointers are fixed up properly
00921         instructionCount = 0;
00922 
00923         for ( i = 0 ; i < numAsmFiles ; i++ ) {
00924             currentFileIndex = i;
00925             currentFileName = asmFileNames[ i ];
00926             currentFileLine = 0;
00927             printf("pass %i: %s\n", passNumber, currentFileName );
00928             ptr = asmFiles[i];
00929             while ( ptr ) {
00930                 ptr = ExtractLine( ptr );
00931                 AssembleLine();
00932             }
00933         }
00934 
00935         // align all segment
00936         for ( i = 0 ; i < NUM_SEGMENTS ; i++ ) {
00937             segment[i].imageUsed = (segment[i].imageUsed + 3) & ~3;
00938         }
00939     }
00940 
00941     // reserve the stack in bss
00942     DefineSymbol( "_stackStart", segment[BSSSEG].imageUsed );
00943     segment[BSSSEG].imageUsed += stackSize;
00944     DefineSymbol( "_stackEnd", segment[BSSSEG].imageUsed );
00945 
00946     // write the image
00947     WriteVmFile();
00948 
00949     // write the map file even if there were errors
00950     WriteMapFile();
00951 }
00952 
00953 
00954 /*
00955 =============
00956 ParseOptionFile
00957 
00958 =============
00959 */
00960 void ParseOptionFile( const char *filename ) {
00961     char        expanded[MAX_OS_PATH];
00962     char        *text, *text_p;
00963 
00964     strcpy( expanded, filename );
00965     DefaultExtension( expanded, ".q3asm" );
00966     LoadFile( expanded, (void **)&text );
00967     if ( !text ) {
00968         return;
00969     }
00970 
00971     text_p = text;
00972 
00973     while( ( text_p = COM_Parse( text_p ) ) != 0 ) {
00974         if ( !strcmp( com_token, "-o" ) ) {
00975             // allow output override in option file
00976             text_p = COM_Parse( text_p );
00977             if ( text_p ) {

void CodeError char *  fmt,
  ...
 

Definition at line 402 of file q3asm.c.

References qboolean, and token.

00411                        {
00412     int     c;

void DefineSymbol char *  sym,
int  value
 

Definition at line 450 of file q3asm.c.

References atoi, Parse(), and token.

00451                        {
00452     Parse();
00453     return atoi( token );
00454 }
00455 
00456 
00457 /*
00458 ==============
00459 ParseExpression
00460 ==============
00461 */
00462 int ParseExpression(void) {
00463     int     i, j;
00464     char    sym[MAX_LINE_LENGTH];
00465     int     v;
00466 
00467     if ( token[0] == '-' ) {
00468         i = 1;
00469     } else {
00470         i = 0;
00471     }
00472 
00473     for ( ; i < MAX_LINE_LENGTH ; i++ ) {
00474         if ( token[i] == '+' || token[i] == '-' || token[i] == 0 ) {
00475             break;
00476         }
00477     }
00478 
00479     memcpy( sym, token, i );
00480     sym[i] = 0;
00481 
00482     if ( ( sym[0] >= '0' && sym[0] <= '9' ) || sym[0] == '-' ) {
00483         v = atoi( sym );
00484     } else {
00485         v = LookupSymbol( sym );
00486     }
00487 
00488     // parse add / subtract offsets
00489     while ( token[i] != 0 ) {
00490         for ( j = i + 1 ; j < MAX_LINE_LENGTH ; j++ ) {
00491             if ( token[j] == '+' || token[j] == '-' || token[j] == 0 ) {
00492                 break;
00493             }
00494         }
00495 
00496         memcpy( sym, token+i+1, j-i-1 );
00497         sym[j-i-1] = 0;
00498 
00499         if ( token[i] == '+' ) {
00500             v += atoi( sym );

Here is the call graph for this function:

void EmitByte segment_t seg,
int  v
 

Definition at line 419 of file q3asm.c.

References lineBuffer, and lineParseOffset.

Referenced by Parse(), and ParseExpression().

00419                                                    {
00420         if ( lineBuffer[ lineParseOffset ] == 0 ) {
00421             return qfalse;
00422         }
00423         lineParseOffset++;
00424     }
00425 

void EmitInt segment_t seg,
int  v
 

Definition at line 432 of file q3asm.c.

References c, lineBuffer, lineParseOffset, and token.

Referenced by Parse().

00434        {
00435         token[len] = c;
00436         len++;
00437         lineParseOffset++;
00438         c = lineBuffer[ lineParseOffset ];
00439     } while (c>32);
00440     
00441     token[len] = 0;

char* ExtractLine char *  data  ) 
 

Definition at line 549 of file q3asm.c.

References token.

00552                      {
00553         return;
00554     }
00555 
00556     hash = HashString( token );
00557 
00558     for ( i = 0 ; i < NUM_SOURCE_OPS ; i++ ) {
00559         if ( hash == opcodesHash[i] && !strcmp( token, sourceOps[i].name ) ) {
00560             int     opcode;
00561             int     expression;
00562 
00563             if ( sourceOps[i].opcode == OP_UNDEF ) {
00564                 CodeError( "Undefined opcode: %s\n", token );
00565             }
00566             if ( sourceOps[i].opcode == OP_IGNORE ) {
00567                 return;     // we ignore most conversions
00568             }
00569 
00570             // sign extensions need to check next parm
00571             opcode = sourceOps[i].opcode;
00572             if ( opcode == OP_SEX8 ) {
00573                 Parse();
00574                 if ( token[0] == '1' ) {
00575                     opcode = OP_SEX8;
00576                 } else if ( token[0] == '2' ) {
00577                     opcode = OP_SEX16;

void HackToSegment segmentName_t  seg  ) 
 

Definition at line 704 of file q3asm.c.

00707                                        {
00708         Parse();
00709         v = ParseExpression();
00710 
00711         HackToSegment( DATASEG );
00712         EmitInt( currentSegment, v );
00713         return;
00714     }

int HashString char *  s  ) 
 

Definition at line 386 of file q3asm.c.

References data.

00386                                                {
00387             break;
00388         }
00389     }
00390     if ( i == MAX_LINE_LENGTH ) {
00391         CodeError( "MAX_LINE_LENGTH" );
00392         return data;
00393     }
00394     memcpy( lineBuffer, data, i );

void InitTables void   ) 
 

Definition at line 984 of file q3asm.c.

References numAsmFiles.

00993                                   {

int LookupSymbol char *  sym  ) 
 

Definition at line 510 of file q3asm.c.

References currentSegment, segment_t::imageUsed, lastSymbol, passNumber, symbol_s::segment, segment, and symbol_s::value.

00516         : I want to put all 32 bit values in the data
00517 segment so they can be byte swapped, and all char data in the lit
00518 segment, but switch jump tables are emited in the lit segment and
00519 initialized strng variables are put in the data segment.
00520 
00521 I can change segments here, but I also need to fixup the
00522 label that was just defined
00523 
00524 Note that the lit segment is read-write in the VM, so strings
00525 aren't read only as in some architectures.
00526 ==============
00527 */
00528 void HackToSegment( segmentName_t seg ) {
00529     if ( currentSegment == &segment[seg] ) {
00530         return;
00531     }
00532 
00533     currentSegment = &segment[seg];
00534     if ( passNumber == 0 ) {
00535         lastSymbol->segment = currentSegment;
00536         lastSymbol->value = currentSegment->imageUsed;
00537     }

int main int  argc,
char **  argv
 

Definition at line 1169 of file q3asm.c.

qboolean Parse void   ) 
 

Definition at line 587 of file q3asm.c.

References CODESEG, EmitByte(), EmitInt(), ParseExpression(), segment, and sourceOps.

Referenced by DefineSymbol().

00587                                                         {
00588                 expression = ParseExpression();
00589 
00590                 // code like this can generate non-dword block copies:
00591                 // auto char buf[2] = " ";
00592                 // we are just going to round up.  This might conceivably
00593                 // be incorrect if other initialized chars follow.
00594                 if ( opcode == OP_BLOCK_COPY ) {
00595                     expression = ( expression + 3 ) & ~3;
00596                 }
00597 
00598                 EmitByte( &segment[CODESEG], opcode );
00599                 EmitInt( &segment[CODESEG], expression );
00600             } else {
00601                 EmitByte( &segment[CODESEG], opcode );
00602             }
00603 
00604             instructionCount++;
00605             return;
00606         }
00607     }
00608 
00609     // call instructions reset currentArgOffset
00610     if ( !strncmp( token, "CALL", 4 ) ) {
00611         EmitByte( &segment[CODESEG], OP_CALL );
00612         instructionCount++;
00613         currentArgOffset = 0;
00614         return;
00615     }
00616 
00617     // arg is converted to a reversed store
00618     if ( !strncmp( token, "ARG", 3 ) ) {
00619         EmitByte( &segment[CODESEG], OP_ARG );

Here is the call graph for this function:

int ParseExpression void   ) 
 

Definition at line 638 of file q3asm.c.

References CODESEG, EmitByte(), instructionCount, OP_POP, and segment.

Referenced by Parse().

00640                                        {
00641         EmitByte( &segment[CODESEG], OP_POP );
00642         instructionCount++;
00643         return;
00644     }
00645 
00646     // address of a parameter is converted to OP_LOCAL
00647     if ( !strncmp( token, "ADDRF", 5 ) ) {
00648         instructionCount++;
00649         Parse();
00650         v = ParseExpression();
00651         v = 16 + currentArgs + currentLocals + v;
00652         EmitByte( &segment[CODESEG], OP_LOCAL );
00653         EmitInt( &segment[CODESEG], v );
00654         return;
00655     }
00656 
00657     // address of a local is converted to OP_LOCAL
00658     if ( !strncmp( token, "ADDRL", 5 ) ) {
00659         instructionCount++;
00660         Parse();
00661         v = ParseExpression();
00662         v = 8 + currentArgs + v;
00663         EmitByte( &segment[CODESEG], OP_LOCAL );
00664         EmitInt( &segment[CODESEG], v );
00665         return;
00666     }
00667 
00668     if ( !strcmp( token, "proc" ) ) {
00669         char    name[1024];
00670 
00671         Parse();                    // function name
00672         strcpy( name, token );
00673 
00674         DefineSymbol( token, instructionCount ); // segment[CODESEG].imageUsed );
00675 
00676         currentLocals = ParseValue();   // locals
00677         currentLocals = ( currentLocals + 3 ) & ~3;
00678         currentArgs = ParseValue();     // arg marshalling
00679         currentArgs = ( currentArgs + 3 ) & ~3;
00680 
00681         if ( 8 + currentLocals + currentArgs >= 32767 ) {
00682             CodeError( "Locals > 32k in %s\n", name );
00683         }
00684 
00685         instructionCount++;

Here is the call graph for this function:

void ParseOptionFile const char *  filename  ) 
 

Definition at line 1136 of file q3asm.c.

int ParseValue void   ) 
 

Definition at line 627 of file q3asm.c.

00631                                        {

void WriteMapFile void   ) 
 

Definition at line 998 of file q3asm.c.

References argc, and Error().

Referenced by main().

00999                     {
01000         Error( "usage: q3asm [-o output] <files> or q3asm -f <listfile>\n" );
01001     }
01002 
01003     start = I_FloatTime ();
01004     InitTables();
01005 
01006     // default filename is "q3asm"
01007     strcpy( outputFilename, "q3asm" );
01008     numAsmFiles = 0;    
01009 
01010     for ( i = 1 ; i < argc ; i++ ) {
01011         if ( argv[i][0] != '-' ) {
01012             break;
01013         }
01014         if ( !strcmp( argv[i], "-o" ) ) {
01015             if ( i == argc - 1 ) {
01016                 Error( "-o must preceed a filename" );
01017             }
01018             strcpy( outputFilename, argv[ i+1 ] );
01019             i++;
01020             continue;
01021         }
01022 

Here is the call graph for this function:

void WriteVmFile void   ) 
 

Definition at line 1029 of file q3asm.c.

01031                               : %s", argv[i] );
01032     }
01033 
01034     // the rest of the command line args are asm files
01035     for ( ; i < argc ; i++ ) {
01036         asmFileNames[ numAsmFiles ] = copystring( argv[ i ] );
01037         numAsmFiles++;
01038     }
01039 
01040     Assemble();
01041 
01042     end = I_FloatTime ();
01043     printf ("%5.0f seconds elapsed\n", end-start);
01044 
01045     return 0;
01046 }
01047 
01048 


Variable Documentation

char* asmFileNames[MAX_ASM_FILES]
 

Definition at line 168 of file q3asm.c.

char* asmFiles[MAX_ASM_FILES]
 

Definition at line 167 of file q3asm.c.

int currentArgOffset
 

Definition at line 182 of file q3asm.c.

int currentArgs
 

Definition at line 181 of file q3asm.c.

int currentFileIndex
 

Definition at line 170 of file q3asm.c.

int currentFileLine
 

Definition at line 172 of file q3asm.c.

char* currentFileName
 

Definition at line 171 of file q3asm.c.

int currentLocals
 

Definition at line 180 of file q3asm.c.

segment_t* currentSegment
 

Definition at line 154 of file q3asm.c.

Referenced by AssembleLine(), and LookupSymbol().

int errorCount
 

Definition at line 159 of file q3asm.c.

Referenced by Com_Error().

int instructionCount
 

Definition at line 189 of file q3asm.c.

Referenced by ParseExpression().

symbol_t* lastSymbol
 

Definition at line 162 of file q3asm.c.

Referenced by LookupSymbol().

char lineBuffer[MAX_LINE_LENGTH]
 

Definition at line 185 of file q3asm.c.

Referenced by EmitByte(), and EmitInt().

int lineParseOffset
 

Definition at line 186 of file q3asm.c.

Referenced by EmitByte(), and EmitInt().

int numAsmFiles
 

Definition at line 166 of file q3asm.c.

Referenced by InitTables().

int numSymbols
 

Definition at line 158 of file q3asm.c.

int opcodesHash[NUM_SOURCE_OPS]
 

Definition at line 378 of file q3asm.c.

char outputFilename[MAX_OS_PATH]
 

Definition at line 30 of file