[llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/Makefile assem.c assem.h buffer.c buffer.h code.c code.h constants.h convert.c convert.h op_tab.c op_tab.h pass1.c pass1.h pass2.c pass2.h pseudo.c pseudo.h record.c record.h scan_line.c scan_line.h stringI.c stringI.h sym_tab.c sym_tab.h
Chris Lattner
lattner at cs.uiuc.edu
Tue Oct 5 11:24:30 PDT 2004
Changes in directory llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler:
Makefile added (r1.1)
assem.c added (r1.1)
assem.h added (r1.1)
buffer.c added (r1.1)
buffer.h added (r1.1)
code.c added (r1.1)
code.h added (r1.1)
constants.h added (r1.1)
convert.c added (r1.1)
convert.h added (r1.1)
op_tab.c added (r1.1)
op_tab.h added (r1.1)
pass1.c added (r1.1)
pass1.h added (r1.1)
pass2.c added (r1.1)
pass2.h added (r1.1)
pseudo.c added (r1.1)
pseudo.h added (r1.1)
record.c added (r1.1)
record.h added (r1.1)
scan_line.c added (r1.1)
scan_line.h added (r1.1)
stringI.c added (r1.1)
stringI.h added (r1.1)
sym_tab.c added (r1.1)
sym_tab.h added (r1.1)
---
Log message:
Another benchmark. This is apparently an assembler for some target I
couldn't figure out. There are also no input files for this :(
Agg, and the source looks like pascal!
---
Diffs of the changes: (+3184 -0)
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/Makefile
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/Makefile:1.1
*** /dev/null Tue Oct 5 13:24:26 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/Makefile Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,6 ----
+ LEVEL = ../../../..
+
+ PROG = assembler
+ LDFLAGS = -lm
+ include $(LEVEL)/MultiSource/Makefile.multisrc
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,109 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================ assem.c ==================================== */
+ /* Main (driving) routine of the assembler. Contains a few globals, opens */
+ /* closes input, output, and temporary files. Calls Pass1 and Pass2 */
+
+ /* to compile (the assembler) use: */
+ /* cc -o assem assem.c pass1.c pass2.c scan_line.c stringI.c sym_tab.c */
+ /* op_tab.c pseudo.c code.c record.c buffer.c convert.c -lm */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <malloc.h>
+ #include <string.h>
+ #include "constants.h"
+ #include "pass1.h"
+ #include "pass2.h"
+ #include "sym_tab.h"
+
+ /* --------------------------------- Globals ------------------------------ */
+ /* MODULE_NAME Name of (program) module currently */
+ /* assembling. */
+ char MODULE_NAME[LABEL_SIZE_1+1];
+
+ /* MAIN_ROUTINE Name of (program) module declared with */
+ /* a START (main routine). */
+ char MAIN_ROUTINE[LABEL_SIZE_1+1];
+
+ /* START_ADDRESS Start Address for program execution. */
+ int START_ADDRESS = -1;
+
+ /* -------------------------------- main ---------------------------------- */
+ int main(int argc,char **argv)
+ {
+ FILE *INPUT_STREAM; /* Input file stream */
+ SYMBOL_TABLE SYM_TAB; /* The symbol table */
+ FILE *TEMP_OUTPUT_STREAM; /* pass1 creates a file that is used as */
+ /* as the input to pass2. */
+ char *TEMP_OUTPUT_FILE_NAME /* Name of the above mentioned file */
+ = "%pass1%";
+ int ERROR = FALSE_1; /* FALSE no errors seen. TRUE seen errors */
+
+ INIT_SYM_TAB(&SYM_TAB); /* Initialize the symbol table */
+
+ if (argc == 1) (void) printf("usage: assem file\n");
+ else {
+ if ( (INPUT_STREAM = fopen(argv[1],"r")) == NULL) {
+ (void) printf("%s: No such file or directory\n",argv[1]);
+ } else {
+ /* --------------------------------- Have a valid file: assemble it */
+ char *LISTING_FILE; /* Name of file to put the listing into */
+ FILE *LISTING_STREAM; /* Stream for listing file */
+ char *OBJECT_FILE; /* Name of object code file */
+ FILE *OBJECT_STREAM; /* Object code stream */
+ int LOOP_COUNTER; /* a loop counter */
+
+ TEMP_OUTPUT_STREAM = fopen(TEMP_OUTPUT_FILE_NAME,"w");
+
+ PASS1(INPUT_STREAM,&SYM_TAB,TEMP_OUTPUT_STREAM);
+ (void) fclose(INPUT_STREAM);
+ (void) fclose(TEMP_OUTPUT_STREAM);
+
+ /* --------------------------------- Get name for LISTING FILE */
+ LISTING_FILE = (char *) malloc((unsigned int) (strlen(argv[1])+5));
+ (void) strcpy(LISTING_FILE,argv[1]);
+ for ((LOOP_COUNTER = strlen(argv[1]));
+ ( (LOOP_COUNTER >= 0) && (LISTING_FILE[LOOP_COUNTER] != '.'));
+ LOOP_COUNTER --);
+ if (LOOP_COUNTER <= 0) LOOP_COUNTER = strlen(argv[1]);
+ (void) strcpy(&(LISTING_FILE[LOOP_COUNTER]),".lst");
+
+ /* --------------------------------- Get name for OBJECT FILE */
+ OBJECT_FILE = (char *) malloc((unsigned int) (strlen(argv[1])+5));
+ (void) strcpy(OBJECT_FILE,argv[1]);
+ (void) strcpy(&(OBJECT_FILE[LOOP_COUNTER]),".obj");
+
+ INPUT_STREAM = fopen(TEMP_OUTPUT_FILE_NAME,"r");
+ LISTING_STREAM = fopen(LISTING_FILE,"w");
+ OBJECT_STREAM = fopen(OBJECT_FILE,"w");
+
+ PASS2(INPUT_STREAM,OBJECT_STREAM,LISTING_STREAM,&SYM_TAB,&ERROR);
+
+ (void) fclose(OBJECT_STREAM);
+ (void) fclose(LISTING_STREAM);
+ (void) fclose(INPUT_STREAM);
+
+ /* -------------------------------- Delete the temporary output file */
+ if (!DEBUG_FLAG_1) {
+ char *TEMP;
+ TEMP = (char *) malloc((unsigned int)
+ (4+strlen(TEMP_OUTPUT_FILE_NAME)));
+ (void) sprintf(TEMP,"rm %s",TEMP_OUTPUT_FILE_NAME);
+ (void) system(TEMP);
+ }
+
+ /* -------------------------------- If errors, delete the object file */
+ if (ERROR) {
+ char *TEMP;
+ TEMP = (char *) malloc((unsigned int)
+ (4+strlen(OBJECT_FILE)));
+ (void) sprintf(TEMP,"rm %s",OBJECT_FILE);
+ (void) system(TEMP);
+ (void) printf("Errors detected. Deleted object file.\n");
+ }
+ }
+ }
+ return 1;
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/assem.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,17 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== assem.h ================================= */
+
+ #include "constants.h"
+
+ /* MODULE_NAME Name of (program) module currently */
+ /* assembling. */
+ extern char MODULE_NAME[LABEL_SIZE_1+1];
+
+ /* MAIN_ROUTINE Name of (program) module declared with */
+ /* a START (main routine). */
+ extern char MAIN_ROUTINE[LABEL_SIZE_1+1];
+
+ /* START_ADDRESS Start Address for program execution. */
+ extern int START_ADDRESS;
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,101 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =========================== buffer.c ==================================== */
+ /* This module was created for 2 purposes: */
+ /* 1) Store Modify records (of object code) till after all text */
+ /* of a module (so that a modify record is always after the text */
+ /* record for the same location) */
+ /* 2) Store Error messages. Sometimes errors are detected that can */
+ /* not be output immediately (in the middle of writting out */
+ /* another record). This allows you to save error messages till */
+ /* able to output them. */
+
+ #include <string.h>
+ #include <stdio.h>
+ #include <malloc.h>
+
+ /* Constants used to determine if being used to store modify records or */
+ /* error messages. */
+ #define MOD_REC_2 0
+ #define ERROR_REC_2 1
+
+
+ /* type BUFFER Linked list of strings */
+ struct BUFFER {
+ char *LINE;
+ struct BUFFER *NEXT;
+ };
+
+
+ /* type BUFFER_TYPE Pointers to both ends of the linked */
+ /* list and whether contains */
+ /* modification records or errors */
+ struct BUFFER_TYPE {
+ struct BUFFER *HEAD_OF_BUFFER;
+ struct BUFFER *TAIL_OF_BUFFER;
+ int KIND;
+ };
+
+
+ /* MOD_REC_BUF GLOBAL buffer for modification records*/
+ struct BUFFER_TYPE MOD_REC_BUF = {NULL,NULL,MOD_REC_2};
+
+ /* ERROR_REC_BUF GLOBAL buffer for error messages */
+ struct BUFFER_TYPE ERROR_REC_BUF = {NULL,NULL,ERROR_REC_2};
+
+
+
+
+ /* ------------------------- OUTPUT_BUFFER --------------------------------- */
+ /* Puts everything in buffer BUF into output stream OUTPUT. PASS (1 or 2) is */
+ /* used as a fix to a problem I. In pass2, I call a procedure used by pass1, */
+ /* which outputs errors in a different format. This is used to, in pass2, */
+ /* convert the pass1 errors. Upon completion the buffer is empty. */
+
+ void OUTPUT_BUFFER(struct BUFFER_TYPE *BUF,FILE *OUTPUT,int PASS)
+ {
+ struct BUFFER *NEXT;
+
+ /* --------------------------------- Step through the linked list, putting */
+ /* --------------------------------- each string on a different line. */
+
+ while ((*BUF).HEAD_OF_BUFFER != NULL) {
+ NEXT =(* (*BUF).HEAD_OF_BUFFER).NEXT;
+ if ((PASS == 2) && !strncmp("eERROR",(*(*BUF).HEAD_OF_BUFFER).LINE,6))
+ (void) fprintf(OUTPUT,"%s\n",&((*(*BUF).HEAD_OF_BUFFER).LINE[1]));
+ else
+ (void) fprintf(OUTPUT,"%s\n",(*(*BUF).HEAD_OF_BUFFER).LINE);
+ free((*(*BUF).HEAD_OF_BUFFER).LINE);
+ free((char *) (*BUF).HEAD_OF_BUFFER);
+ (*BUF).HEAD_OF_BUFFER = NEXT;
+ }
+ (*BUF).TAIL_OF_BUFFER = NULL;
+ }
+
+
+ /* ----------------------- ADD_TO_END_OF_BUFFER ---------------------------- */
+ /* Puts the string INPUT_STR, on the end of the buffer pointed to by BUF. */
+
+ void ADD_TO_END_OF_BUFFER(struct BUFFER_TYPE *BUF,char *INPUT_STR)
+ {
+ char *TEMP_LINE;
+ /* --------------------------------- Create new element, and put on buffr */
+ if ((*BUF).HEAD_OF_BUFFER == NULL) {
+ (*BUF).HEAD_OF_BUFFER = (struct BUFFER *) malloc(sizeof(struct BUFFER));
+ (*BUF).TAIL_OF_BUFFER = (*BUF).HEAD_OF_BUFFER;
+ } else {
+ (*(*BUF).TAIL_OF_BUFFER).NEXT = (struct BUFFER *) malloc(sizeof(struct BUFFER));
+ (*BUF).TAIL_OF_BUFFER = (*(*BUF).TAIL_OF_BUFFER).NEXT;
+ }
+
+ /* --------------------------------- Initialize the buffer element correctly */
+ (*(*BUF).TAIL_OF_BUFFER).LINE = TEMP_LINE =
+ malloc((unsigned int) (strlen(INPUT_STR) + 2));
+ if ((*BUF).KIND == MOD_REC_2) {
+ TEMP_LINE[0] = 'M';
+ (void) strcpy( &(TEMP_LINE[1]),INPUT_STR);
+ } else
+ (void) strcpy( TEMP_LINE,INPUT_STR);
+ (*(*BUF).TAIL_OF_BUFFER).NEXT = NULL;
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/buffer.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,54 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ================================ buffer.h =============================== */
+ /* This module was created for 2 purposes: */
+ /* 1) Store Modify records (of object code) till after all text */
+ /* of a module (so that a modify record is always after the text */
+ /* record for the same location) */
+ /* 2) Store Error messages. Sometimes errors are detected that can */
+ /* not be output immediately (in the middle of writting out */
+ /* another record). This allows you to save error messages till */
+ /* able to output them. */
+
+ /* type BUFFER Linked list of strings */
+ struct BUFFER {
+ char *LINE;
+ struct BUFFER *NEXT;
+ };
+
+ /* type BUFFER_TYPE Pointers to both ends of the linked */
+ /* list and whether contains */
+ /* modification records or errors */
+ struct BUFFER_TYPE {
+ struct BUFFER *HEAD_OF_BUFFER;
+ struct BUFFER *TAIL_OF_BUFFER;
+ int KIND;
+ };
+
+
+ /* MOD_REC_BUF GLOBAL buffer for modification records*/
+ extern struct BUFFER_TYPE MOD_REC_BUF;
+
+ /* ERROR_REC_BUF GLOBAL buffer for error messages */
+ extern struct BUFFER_TYPE ERROR_REC_BUF;
+
+ /* ------------------------- OUTPUT_BUFFER --------------------------------- */
+ /* 3 parameters: */
+ /* 1) struct BUFFER_TYPE *BUF; the buffer to output */
+ /* 2) FILE *OUTPUT; the stream to output to */
+ /* 3) int PASS; which pass called from 1 = pass1, */
+ /* Puts everything in buffer BUF into output stream OUTPUT. PASS (1 or 2) is */
+ /* used as a fix to a problem I. In pass2, I call a procedure used by pass1, */
+ /* which outputs errors in a different format. This is used to, in pass2, */
+ /* convert the pass1 errors. Upon completion the buffer is empty. */
+ extern void OUTPUT_BUFFER();
+
+ /* ----------------------- ADD_TO_END_OF_BUFFER ---------------------------- */
+ /* 2 parameters: */
+ /* 1) struct BUFFER_TYPE *BUF; the buffer to add onto */
+ /* 2) char *INPUT_STR; what to add onto the buffer */
+ /* Puts the string INPUT_STR, on the end of the buffer pointed to by BUF. */
+ extern void ADD_TO_END_OF_BUFFER();
+
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,506 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== code.c =================================== */
+ /* Does the 'real' work of PASS2. Produces one listing file line for a */
+ /* assembly instruction and all object file records, except those from pass1 */
+ /* EVERY line of listing file is produced in this module (except pass1 */
+ /* error messages). */
+ /* Before this is called everything the assembler needs to know is figured */
+ /* and this does (most of) the code generation. */
+
+ #include <math.h>
+ #include <malloc.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include "pass1.h"
+ #include "stringI.h"
+ #include "scan_line.h"
+ #include "convert.h"
+ #include "sym_tab.h"
+ #include "record.h"
+ #include "assem.h"
+ #include "constants.h"
+ #include "buffer.h"
+ #include "op_tab.h"
+
+ /* ------------------------------- PSEUDO_CODE (local) --------------------- */
+ /* Generates listing line (except location counter which is handled */
+ /* elsewhere) for source lines dealing with PSEUDO OPs. Produces object */
+ /* records for pseudo ops that could not be figured at pass1 (line Header */
+ /* records; do not know length until pass2). */
+
+ void PSEUDO_CODE(char *OPERATOR,FILE *INPUT_STREAM,FILE *OBJECT_STREAM,
+ FILE *LISTING_STREAM)
+ {
+ char CH; /* a character for looking ahead in the */
+ /* input stream. */
+
+ /* -------------------------------- Output any generated machine code */
+ if ( (strcmp(OPERATOR,"WORD")) && (strcmp(OPERATOR,"BYTE")))
+ /* -------------------------------- Only BYTE and WORD generate code */
+ /* (leave code part of listing blank) */
+ /* COLUMNS 8 - 17 8901234567 */
+ (void) fprintf(LISTING_STREAM," ");
+ else {
+ /* ---------------- Must look into pass1 output to see if any code generated */
+ CH = fgetc(INPUT_STREAM);
+ if (CH == 't') {
+ /* -------------- Code in text record. Put into text record and listing file */
+ /* -------------- put code into object file text records, and print on */
+ /* -------------- listing line. */
+ int LOCATION;
+ char TEMP_CH;
+ char *REST_OF_LINE;
+
+ (void) fscanf(INPUT_STREAM,"%d%c",&LOCATION,&TEMP_CH);
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+
+ (void) fprintf(LISTING_STREAM,"%s",REST_OF_LINE);
+ if (strlen(REST_OF_LINE) <= 8) {
+ int I;
+ for (I=(strlen(REST_OF_LINE)+1);I<=10;I++)
+ (void) fprintf(LISTING_STREAM," ");
+ } else
+ (void) fprintf(LISTING_STREAM,
+ /* COLUMNS 1 - 8 123456789012345678 */
+ " {source on next line}\n ");
+
+ if ( TEMP_CH == 'W')
+ ADD_TO_TEXT_RECORD(REST_OF_LINE,LOCATION,OBJECT_STREAM);
+ else {
+ char TEMP[HEX_CHAR_PER_BYTE_1+1];
+ int DELTA = 0;
+
+ for (TEMP[HEX_CHAR_PER_BYTE_1]='\0';!eoln(*REST_OF_LINE);
+ REST_OF_LINE+=HEX_CHAR_PER_BYTE_1) {
+ (void) strncpy(TEMP,REST_OF_LINE,HEX_CHAR_PER_BYTE_1);
+ ADD_TO_TEXT_RECORD(TEMP,(LOCATION+DELTA),OBJECT_STREAM);
+ DELTA ++;
+ }
+ }
+ } /* END if (CH == 't')*/
+ else {
+ /* --------------- No code was generated for the BYTE/WORD because of errors */
+ (void) ungetc(CH,INPUT_STREAM);
+ /* COLUMNS 8 - 17 8901234567 */
+ (void) fprintf(LISTING_STREAM," ");
+ }
+ }
+ }
+
+ /* ------------------------ GET_REG (local) -------------------------------- */
+ /* Converts the next thing in a string (pointed to by REG) into the number */
+ /* that corresponds to the register with that name. Returns -1 if next thing */
+ /* is not a register. when done, *REG will point to the character immediately*/
+ /* following the register name. */
+
+ int GET_REG(char **REG)
+ {
+ int VAL;
+ switch (**REG) {
+ case 'A':
+ VAL = 0;
+ break;
+ case 'X':
+ VAL = 1;
+ break;
+ case 'L':
+ VAL = 2;
+ break;
+ case 'B':
+ VAL = 3;
+ break;
+ case 'S':
+ if (*((*REG)+1) == 'W') {
+ (*REG) ++;
+ VAL = 9;
+ } else VAL = 4;
+ break;
+ case 'T':
+ VAL = 5;
+ break;
+ case 'P':
+ if (*((*REG)+1) == 'C') {
+ (*REG) ++;
+ VAL = 8;
+ } else VAL = -1;
+ break;
+ default:
+ VAL = -1;
+ break;
+ }
+ (*REG)++;
+ return VAL;
+ }
+
+
+
+ /* ------------------------- SET_BITS_TO (local) --------------------------- */
+ /* CODE is a 32 character string. Each element in that string is either a '0'*/
+ /* or a '1' and represents the machine code for an instruction. SET_BITS_TO */
+ /* sets the bits between LOW_BIT and HIGH_BIT (inclusive) so that they are */
+ /* the binary equivalen to VALUE (i.e. make is so that: */
+ /* SUM i=0 to (HIGH_BIT-LOW_BIT) {CODE[HIGH_BIT-i]*2^i} = VALUE. */
+
+ void SET_BITS_TO(int LOW_BIT,int HIGH_BIT,int VALUE,char *CODE)
+ {
+ int I; /* Loop counter variable */
+ int BIT; /* BIT of code to set next */
+ int VALUE_BIT; /* one BIT from VALUE to be moved to CODE*/
+
+ if ((HIGH_BIT < LOW_BIT) || (HIGH_BIT >= LARGEST_INSTRUCT_SIZE_1))
+ (void) printf("SET_BITS_TO called improperly.\n");
+ else {
+ BIT = HIGH_BIT;
+ for (I= ((int) pow(2.0,1.0*(HIGH_BIT-LOW_BIT))); I > 0; I /= 2) {
+ VALUE_BIT = VALUE - (VALUE/2)*2;
+ VALUE /= 2;
+ CODE[BIT] = ((char) VALUE_BIT) + '0';
+ BIT --;
+ }
+ if (VALUE != 0)
+ (void) printf("SET_BITS_TO called improperly, VALUE too large.\n");
+ }
+ }
+
+ /* ----------------------- PRT_CODE (local) -------------------------------- */
+ /* Output to OBJECT_STREAM, the number represented by the first BYTES bytes */
+ /* of the [binary] string CODE. Also add the number to the TEXT Record of the*/
+ /* object file (stream name is OBJECT_STREAM) at LOCATION. Output is */
+ /* hexidecimal. */
+ void PRT_CODE(char *CODE,int BYTES,int LOCATION,FILE *LISTING_STREAM,
+ FILE *OBJECT_STREAM)
+ {
+ int BYTE_COUNTER; /* byte to output next */
+ int BIT_COUNTER; /* bit (of byte) to process next */
+ int CH;
+ char NUM_STR[LARGEST_INSTRUCT_SIZE_1/4];
+
+ if (BYTES*4 > LARGEST_INSTRUCT_SIZE_1)
+ (void) printf("PRT_CODE called improperly.\n");
+ else {
+ /* ------- Make a hex string representing the number. */
+ for (BYTE_COUNTER=0;BYTE_COUNTER < BYTES; BYTE_COUNTER ++) {
+ CH = 0;
+ for (BIT_COUNTER=0; BIT_COUNTER < 4; BIT_COUNTER ++)
+ CH = CH * 2 + ((int)
+ CHAR_TO_DIGIT(CODE[BYTE_COUNTER*4+BIT_COUNTER],2));
+ if ( (CH >= 0) && (CH <= 9))
+ NUM_STR[BYTE_COUNTER] = (char) CH + '0';
+ else NUM_STR[BYTE_COUNTER] = (char) (CH - 10) + 'A';
+ }
+ NUM_STR[BYTES] = '\0';
+
+ /* ----------------------- Put Number into listing stream and object stream. */
+ (void) fprintf(LISTING_STREAM,"%s",NUM_STR);
+ ADD_TO_TEXT_RECORD(NUM_STR,LOCATION,OBJECT_STREAM);
+
+ for (BYTE_COUNTER = BYTES; BYTE_COUNTER < (LARGEST_INSTRUCT_SIZE_1/4);
+ BYTE_COUNTER ++)
+ (void) fprintf(LISTING_STREAM," ");
+ }
+ }
+ /* ------------------------------- REAL_CODE (local) ----------------------- */
+ /* Generates listing line (except location counter which is handled */
+ /* elsewhere) for source lines dealing with NON-PSEUDO OPs ('real' ops). */
+ /* Produces object records for real ops. It also produces the text and */
+ /* modification records (of object file) assocated with these source lines. */
+
+ void REAL_CODE(struct OP_ENTRY *OP_CODE,int EXTENDED,char *ARGUMENTS,
+ int LOCATION,SYMBOL_TABLE *SYM_TAB,FILE *OBJECT_STREAM,
+ FILE *LISTING_STREAM,int *ERROR)
+ {
+ char INSTRUCT_CODE[LARGEST_INSTRUCT_SIZE_1+1];
+ int I; /* loop counter */
+ int REG_NUMB; /* REGister NUMBer. Temporay storage*/
+
+ INSTRUCT_CODE[LARGEST_INSTRUCT_SIZE_1] = '\0';
+ for (I=0;I<LARGEST_INSTRUCT_SIZE_1;I++) INSTRUCT_CODE[I] = '0';
+
+ SET_BITS_TO(0,7,(CHAR_TO_DIGIT((*OP_CODE).OPCODE[0],16)*16 +
+ CHAR_TO_DIGIT((*OP_CODE).OPCODE[1],16)),
+ INSTRUCT_CODE);
+
+ if ((*OP_CODE).FORMAT == ONE) {
+ /* ********************* Process FORMAT 1 instructions (easy) ************** */
+ PRT_CODE(INSTRUCT_CODE,2,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ } /* END format ONE */
+
+ if ((*OP_CODE).FORMAT == TWO) {
+ /* ********************* Process FORMAT 2 instructions ********************* */
+ if ((*OP_CODE).OPERAND == NUM) {
+ /* --------------------- One operatand which is a number 0-4 */
+ if ((*ARGUMENTS >= '0') && (*ARGUMENTS <= '4'))
+ SET_BITS_TO(8,11,(int) ((*ARGUMENTS) - '0'),INSTRUCT_CODE);
+ else {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[43]: Illegal argument to SVC.");
+ (*ERROR) = TRUE_1;
+ }
+ ARGUMENTS ++;
+ } else
+ /* --------------------- First (maybe only) argument must be a register. */
+ /* get it. */
+ if ((REG_NUMB = GET_REG(&ARGUMENTS)) < 0) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[45]: Expected a valid register.");
+ (*ERROR) = TRUE_1;
+ ARGUMENTS ++;
+ } else {
+ SET_BITS_TO(8,11,REG_NUMB,INSTRUCT_CODE);
+ if ((*OP_CODE).OPERAND != REG)
+ /* -------------------- Two argument command, Get second after skipping comma*/
+ if ((*ARGUMENTS) != ',') {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[46]: Expected a comma after the first register.");
+ (*ERROR) = TRUE_1;
+ ARGUMENTS ++;
+ } else {
+ ARGUMENTS ++;
+ if ((*OP_CODE).OPERAND == REG_NUM) {
+ /* -------------------- Second argument must be a number 1-16 */
+ REG_NUMB = CHAR_TO_DIGIT(*ARGUMENTS,10);
+ ARGUMENTS ++;
+
+ if (REG_NUMB < 0) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[49]: Expected a number 1-16 after comma.");
+ (*ERROR) = TRUE_1;
+ ARGUMENTS ++;
+ } else {
+ if (CHAR_TO_DIGIT(*ARGUMENTS,10) >= 0) {
+ REG_NUMB = REG_NUMB*10+CHAR_TO_DIGIT(*ARGUMENTS,10);
+ ARGUMENTS ++;
+ REG_NUMB --;
+ } else REG_NUMB --;
+ if ((REG_NUMB < 0) || (REG_NUMB > 15)) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[49]: Expected a number 1-16 after comma.");
+ (*ERROR) = TRUE_1;
+ }
+ else SET_BITS_TO(12,15,REG_NUMB,INSTRUCT_CODE);
+ }
+ } else {
+ /* ---------------------- Second argument must be a register. */
+ if ((REG_NUMB = GET_REG(&ARGUMENTS)) < 0) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[47]: Expected a valid register after the comma.");
+ (*ERROR) = TRUE_1;
+ } else
+ SET_BITS_TO(12,15,REG_NUMB,INSTRUCT_CODE);
+ }
+ }
+ }
+
+ /* ---------------------- make sure nothing illegal after argument[s] */
+ if (!IS_BLANK_OR_TAB(*ARGUMENTS) && !eoln(*ARGUMENTS)) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[44]: Expected a <space> after the operand.");
+ (*ERROR) = TRUE_1;
+ }
+
+ PRT_CODE(INSTRUCT_CODE,4,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ } /* END format TWO */
+
+
+ if ((*OP_CODE).FORMAT == THREE_FOUR) {
+ /* ********************** Process FORMAT 3/4 instructions ****************** */
+ int VALUE; /* value of argument */
+ int WHAT_KIND = ABSOLUTE_OR_RELATIVE_1; /* type of argument */
+
+ /* ------ set extended bit correctly */
+ SET_BITS_TO(11,11,EXTENDED,INSTRUCT_CODE);
+ if ((*OP_CODE).OPERAND == NONE) {
+ /* ------- RSUB has no arguments... easy */
+ SET_BITS_TO(6,7,3,INSTRUCT_CODE);
+ if (EXTENDED)
+ PRT_CODE(INSTRUCT_CODE,8,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ else
+ PRT_CODE(INSTRUCT_CODE,6,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ } else {
+ /* ------ check for immediate or indirect mode, and set the bits accordingly */
+ switch (*ARGUMENTS) {
+ case '@':
+ SET_BITS_TO(6,6,1,INSTRUCT_CODE);
+ ARGUMENTS ++;
+ break;
+ case '#':
+ SET_BITS_TO(7,7,1,INSTRUCT_CODE);
+ ARGUMENTS ++;
+ break;
+ default:
+ SET_BITS_TO(6,7,3,INSTRUCT_CODE);
+ }
+ /* ------- get the value of the argument and the type (kind) of that argument*/
+ VALUE = GET_EXPRESSION(&ARGUMENTS,MEM_ADDR_SIZE_1+1,
+ LOCATION+1,SYM_TAB,&WHAT_KIND);
+
+ if ( ERROR_REC_BUF.HEAD_OF_BUFFER != NULL) (*ERROR) = TRUE_1;
+ if ( ((*ARGUMENTS) == ',') && (*(ARGUMENTS+1) == 'X')) {
+ ARGUMENTS += 2;
+ SET_BITS_TO(8,8,1,INSTRUCT_CODE);
+ }
+
+ if (EXTENDED) {
+ char MOD_REC[9];
+ /* ------ 2's complement negative numbers */
+ if (VALUE < 0) VALUE = MEM_SIZE_1 + VALUE;
+ if (WHAT_KIND == RELATIVE_VALUE_1) {
+ NUM_TO_STR(LOCATION+1,16,6,MOD_REC);
+ (void) strcat(MOD_REC,"05");
+ ADD_TO_END_OF_BUFFER(&MOD_REC_BUF,MOD_REC);
+ }
+ SET_BITS_TO(12,31,VALUE,INSTRUCT_CODE);
+ PRT_CODE(INSTRUCT_CODE,8,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ } else {
+ /* ------- format 3's */
+ if (WHAT_KIND == EXTERN_VALUE_1) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[53]: EXTREF label can not be used in a format THREE instruction.");
+ (*ERROR) = TRUE_1;
+ VALUE = 0;
+ }
+ if (WHAT_KIND == RELATIVE_VALUE_1)
+ VALUE = VALUE - (LOCATION + 3);
+ if ( ( (WHAT_KIND == RELATIVE_VALUE_1) &&
+ (VALUE >= (MAX_PC_RELATIVE_1/2 ))) ||
+ ( (WHAT_KIND != RELATIVE_VALUE_1) &&
+ (VALUE >= (MAX_PC_RELATIVE_1)))) {
+
+ if (WHAT_KIND == RELATIVE_VALUE_1)
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[51]: Location is not within PC relative range.");
+ else
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[52]: Constant too large for a format THREE instruction.");
+ (*ERROR) = TRUE_1;
+ VALUE = 0;
+ }
+
+
+ if (VALUE < 0) {
+ /* --------- 2's complement negative values */
+ VALUE = MAX_PC_RELATIVE_1 + VALUE;
+ if ( (VALUE >= MAX_PC_RELATIVE_1) ||
+ (VALUE < MAX_PC_RELATIVE_1 /2) ) {
+ if (WHAT_KIND == RELATIVE_VALUE_1)
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[51]: Location is not within PC relative range.");
+ else
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[52]: Constant too large for a format THREE instruction.");
+ (*ERROR) = TRUE_1;
+ VALUE = 0;
+ }
+ }
+
+ SET_BITS_TO(12,23,VALUE,INSTRUCT_CODE);
+ if (WHAT_KIND == RELATIVE_VALUE_1)
+ SET_BITS_TO(10,10,1,INSTRUCT_CODE);
+ PRT_CODE(INSTRUCT_CODE,6,LOCATION,LISTING_STREAM,OBJECT_STREAM);
+ }
+ if (!IS_BLANK_OR_TAB(*ARGUMENTS) && !eoln(*ARGUMENTS)) {
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,
+ "ERROR[44]: Expected a <space> after the operand.");
+ (*ERROR) = 1;
+ }
+ }
+ } /* END format THREE_FOUR */
+
+ (void) fprintf(LISTING_STREAM," ");
+ }
+
+ /* ================================= CODE ================================== */
+ /* Determines the location counter value for a line, puts it into the */
+ /* listing stream and calls the correct procedures to output the code */
+ void CODE(FILE *INPUT_STREAM,SYMBOL_TABLE *SYM_TAB,FILE *OBJECT_STREAM,
+ FILE *LISTING_STREAM,int *ERROR)
+ {
+ char LABEL[LABEL_SIZE_1+1]; /* label on the source line */
+ char OPERATOR[LABEL_SIZE_1+1]; /* operator on the source line */
+ char *ARGUMENTS; /* source line after operator */
+ char *INPUT_LINE;
+ int LOCATION_COUNTER;
+ int EXTENDED; /* is this an extended instruction? */
+ struct OP_ENTRY *OP_CODE;
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+
+ (void) fscanf(INPUT_STREAM,"%d",&LOCATION_COUNTER);
+ (void) getc(INPUT_STREAM); /* remove space after s */
+
+ SCAN_LINE(LOCATION_COUNTER,&INPUT_LINE,LABEL,&EXTENDED,OPERATOR,&ARGUMENTS,
+ pass2,(FILE *) NULL,INPUT_STREAM);
+
+ CAPITALIZE_STRING(LABEL);
+ CAPITALIZE_STRING(OPERATOR);
+
+ OP_CODE = LOOK_UP_OP(OPERATOR);
+ if (!strcmp(LABEL,"") && !strcmp(OPERATOR,"") && (EXTENDED == 0))
+ /* ----- blank source line */
+ /* 123456789012345678 */
+ (void) fprintf(LISTING_STREAM," %s\n",INPUT_LINE);
+ else {
+ if (!strcmp(OPERATOR,"")) {
+ /* --------- a no-op */
+ PRT_NUM(LOCATION_COUNTER,16,6,LISTING_STREAM);
+ (void) fprintf(LISTING_STREAM," ");
+ }
+
+ /* OUTPUT blanks for address, if PSEUDO OP that doesn't display a location */
+ else if ((*OP_CODE).OPERAND == PSEUDO_NOLOC)
+ /* 1234567 */
+ (void) fprintf(LISTING_STREAM," ");
+
+
+ else if ((*OP_CODE).OPERAND == PSEUDO_ADDR) {
+ /* -------- OUTPUT value as address if START,CSECT, or EQU */
+ if (!strcmp(OPERATOR,"EQU")) {
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL,SYM_TAB);
+ if (TABLE_ENTRY == NULL)
+ LOCATION_COUNTER = 0;
+ else LOCATION_COUNTER = (*TABLE_ENTRY).LOCATION;
+ } else {
+ if (!strcmp(LABEL,""))
+ GET_NEXT_MISSING_LABEL(LABEL,SYM_TAB);
+ TABLE_ENTRY = LOOK_UP_SYMBOL(LABEL,LABEL,SYM_TAB);
+ if (TABLE_ENTRY == NULL) {
+ (void) printf(
+ "CODE: Something is wrong with code. This shouldn't be executed.\n");
+ /* ------ In all other case output the location counter and the address */
+ } else LOCATION_COUNTER = (*TABLE_ENTRY).LOCATION;
+ }
+
+ PRT_NUM(LOCATION_COUNTER,16,6,LISTING_STREAM);
+ (void) fprintf(LISTING_STREAM," ");
+ }
+ else {
+ PRT_NUM(LOCATION_COUNTER,16,6,LISTING_STREAM);
+ (void) fprintf(LISTING_STREAM," ");
+ }
+
+ {
+ char *SAVE_LINE;
+
+ /* SAVE the source line so that other routines can mess it up without */
+ /* worrying. This was necessary because PSEUDO_CODE might have to look a */
+ /* whole line ahead in the input */
+ SAVE_LINE = malloc((unsigned int) (strlen(INPUT_LINE) + 1));
+ (void) strcpy(SAVE_LINE,INPUT_LINE);
+ CAPITALIZE_STRING(ARGUMENTS);
+
+ /* call correct procedure to produce the code. */
+ if ((*OP_CODE).FORMAT == NOT_FOUND)
+ /* COLUMNS 8 - 17 8901234567 */
+ (void) fprintf(LISTING_STREAM," ");
+ else if ((*OP_CODE).FORMAT == PSEUDO)
+ PSEUDO_CODE(OPERATOR,INPUT_STREAM,OBJECT_STREAM,LISTING_STREAM);
+ else
+ REAL_CODE(OP_CODE,EXTENDED,ARGUMENTS,LOCATION_COUNTER,
+ SYM_TAB,OBJECT_STREAM,LISTING_STREAM,ERROR);
+
+ (void) fprintf(LISTING_STREAM,"%s\n",SAVE_LINE);
+ free(SAVE_LINE);
+ }
+ }
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/code.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,22 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =============================== code.h ================================== */
+ /* Does the 'real' work of PASS2. Produces one listing file line for a */
+ /* assembly instruction and all object file records, except those from pass1 */
+ /* EVERY line of listing file is produced in this module (except pass1 */
+ /* error messages). */
+ /* Before this is called everything the assembler needs to know is figured */
+ /* and this does (most of) the code generation. */
+
+
+ /* ================================= CODE ================================== */
+ /* 5 parameters: */
+ /* 1) FILE *INPUT_STREAM; */
+ /* 2) FILE *OBJECT_STREAM; */
+ /* 3) FILE *LISTING_STREAM; */
+ /* 4) SYMBOL_TABLE *SYM_TAB; symbol table to use */
+ /* 5) int *ERROR; has an error been found (true/false)*/
+ /* Determines the location counter value for a line, puts it into the */
+ /* listing stream and calls the correct procedures to output the code */
+ extern void CODE();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/constants.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/constants.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/constants.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,61 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================= constants.h =============================== */
+ /* A collection of commonly used constants for the assembler. */
+
+
+ /* DEBUG_FLAG_1 Controls whether certain lines of the program. */
+ /* Execution or non-execution of these lines aids in */
+ /* Debugging the program. */
+ #define DEBUG_FLAG_1 0
+
+ /* LABEL_SIZE_1 Size of the largest valid LABEL in characters */
+ #define LABEL_SIZE_1 8
+
+ /* MEM_SIZE_1 Size of SIC/XE main memory in bytes */
+ /* NOTE: 2^20 = 1048576 */
+ #define MEM_SIZE_1 1048576
+
+ /* MEM_ADDR_SIZE_1 Number of BITS in an address {log2(MEM_SIZE_1)} */
+ #define MEM_ADDR_SIZE_1 20
+
+ /* BITS_PER_WORD_1 Number of BITS in a WORD */
+ #define BITS_PER_WORD_1 24
+
+ /* MAX_INT_1 Biggest integer+1: 2^BITS_PER_WORD_1 */
+ #define MAX_INT_1 16777216
+
+ /* BITS_PER_HALFBYTE_1 Number of BITS in a Half BYTE */
+ #define BITS_PER_HALFBYTE_1 4
+
+ /* BITS_PER_BYTE_2 Number of BITS in a BYTE */
+ #define BITS_PER_BYTE_2 8
+
+ /* HEX_CHAR_PER_BYTE_1 Number of hexidecimal characters (ASCII) must be */
+ /* used to produce a 1 BYTE value. */
+ #define HEX_CHAR_PER_BYTE_1 2
+
+ /* LARGEST_INSTRUCT_SIZE_1 Size in BITS of the the largest instruction in */
+ /* SIC/XE. Format 4 is 32 bits */
+ #define LARGEST_INSTRUCT_SIZE_1 32
+
+ /* MAX_PC_RELATIVE_1 Smallest number that will NOT fit in a PC relative*/
+ /* address. {4096 = 2^12} */
+ #define MAX_PC_RELATIVE_1 4096
+
+ /* GLOBAL_1 Module name for Global labels -- used by LOADER. */
+ #define GLOBAL_1 "_GLOBAL "
+
+ /* -------------------------- Boolean Constants ---------------------------- */
+ #define FALSE_1 0
+ #define TRUE_1 1
+
+
+ /* ------------------- Expression types (LABELS,CONSTANTS,etc) ------------- */
+ #define ABSOLUTE_OR_RELATIVE_1 0 /* Don't know type */
+ #define ABSOLUTE_VALUE_1 1 /* Absolute expressions */
+ #define RELATIVE_VALUE_1 2 /* Relative expressions */
+ #define EXTERN_VALUE_1 3 /* An external reference */
+
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,352 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================= convert.c ================================= */
+ /* Contains routines that convert one thing to another. Most of the routines */
+ /* deal with converting a number to a string of that number in some base, or */
+ /* converting a string (assuming some base) into an integer. Basically */
+ /* just a file of miscellaneous 'useful' routines. */
+ #include <stdio.h>
+ #include <string.h>
+ #include <math.h>
+ #include <malloc.h>
+ #include "sym_tab.h"
+ #include "constants.h"
+ #include "scan_line.h"
+ #include "assem.h"
+ #include "buffer.h"
+
+
+ /* MISSING_LABEL_NAME Sections need names because the symbol */
+ /* requires module names. MISSING_LABEL_NAME */
+ /* is a global that is the name to the next */
+ /* section that needs a name. */
+ char MISSING_LABEL_NAME[3] = "_!";
+
+ /* ------------------------ RESET_MISSING_LABEL_NAME ----------------------- */
+ /* Between pass1 and pass2, MISSING_LABEL_NAME must be reset to its */
+ /* orginal value. This procedure does this. */
+ void RESET_MISSING_LABEL_NAME()
+ {
+ (void) strcpy(MISSING_LABEL_NAME,"_!");
+ }
+
+ /* ------------------------ GET_NEXT_MISSING_LABEL ------------------------- */
+ /* Puts MISSING_LABEL_NAME into string LABEL, and puts it into the symbol */
+ /* table. It then changes MISSING_LABEL_NAME to some other unique name. */
+ /* NOTE: this will only return about 90 unique names, after that it returns */
+ /* the same name repeadily. This would result only some additional */
+ /* previously defined label error messages. Never called when executed */
+ /* on a source with no errors. */
+ void GET_NEXT_MISSING_LABEL(char *LABEL,SYMBOL_TABLE *SYM_TAB)
+ {
+ char *CH;
+
+ (void) strcpy(LABEL,MISSING_LABEL_NAME);
+ CH = &(MISSING_LABEL_NAME[strlen(MISSING_LABEL_NAME)-1]);
+ if ((*CH) < '\127') (*CH) = (*CH) + '\1';
+ (void) INSERT_IN_SYM_TAB(MODULE_NAME,LABEL,0,RELATIVE,SYM_TAB);
+ }
+
+
+ /* ---------------------------- BLANK_STR ---------------------------------- */
+ /* Set characters 0-7 of STRING to blank and make the 8th character NULL */
+ /* ie. a 8 character string of blanks. */
+ void BLANK_STR(char *STRING)
+ {
+ int I;
+ for (I=0;I < LABEL_SIZE_1; I ++)
+ STRING[I] = ' ';
+ STRING[LABEL_SIZE_1] = '\0';
+ }
+
+ /* ------------------------ CHAR_TO_DIGIT ---------------------------------- */
+ /* Convert a character (CH) into its integer value give base NUM_BASE. Return*/
+ /* -1 if it is not a valid digit in that base. */
+ int CHAR_TO_DIGIT(char CH,int NUM_BASE)
+ {
+ int DIGIT = -1;
+ if ( (CH >= '0') && (CH <= '9') ) DIGIT = (int) (CH - '0');
+ if ( (CH >= 'A') && (CH <= 'Z') ) DIGIT = ((int) (CH - 'A'))+10;
+ if (DIGIT >= NUM_BASE) DIGIT = -1;
+ return DIGIT;
+ }
+
+
+ /* ------------------------- NUM_TO_STR ------------------------------------ */
+ /* Put into STR the string with LEN digits that represents the number NUM */
+ /* in base BASE (eg. NUM_TO_STR(10,16,3,STR) puts "00A" in STR). */
+ void NUM_TO_STR(int NUM,int BASE,int LEN,char *STR)
+ {
+ int I; /* loop counter */
+ int DIGIT; /* one digit in base specified of NUM */
+
+ STR[LEN] = '\0';
+ for (I=(LEN-1); I>=0; I--) {
+ DIGIT = NUM - (NUM/BASE) * BASE;
+ NUM /= BASE;
+ if ((DIGIT >= 0) && (DIGIT <= 9))
+ STR[I] = (char) DIGIT + '0';
+ else STR[I] = (char) (DIGIT-10) + 'A';
+ }
+ if (NUM != 0)
+ (void) printf("NUM_TO_STR called illegally.\n");
+ }
+
+ /* -------------------------- PRT_NUM ------------------------------------- */
+ /* Output (to stream OUTPUT) the string with LEN digits that represents the */
+ /* number NUM in base BASE (eg. NUM_TO_STR(20,16,2,STR) puts "14" in STR). */
+ void PRT_NUM(int NUM,int NUM_BASE,int LEN,FILE *OUTPUT)
+ {
+ int COUNT; /* loop counter */
+ int MAX_NUM; /* Biggest number can represent with LEN */
+ /* digits in base BASE */
+ int DIGIT; /* One digit in base specified of NUM */
+
+ MAX_NUM = ((int) pow((NUM_BASE*1.0),(LEN-1)*1.0));
+
+ if (NUM < 0) NUM = MAX_NUM*NUM_BASE + NUM;
+
+ if (NUM >= MAX_NUM * NUM_BASE)
+ (void) printf("ASSEMBLER ERROR: PRT_NUM called illegally.\n");
+
+ for (COUNT= MAX_NUM; COUNT >= 1; COUNT /= NUM_BASE) {
+ DIGIT = NUM / COUNT;
+ NUM = NUM - DIGIT*COUNT;
+ if ((DIGIT >= 0) && (DIGIT <= 9))
+ (void) fprintf(OUTPUT,"%c",(char) (DIGIT + '0'));
+ else (void) fprintf(OUTPUT,"%c",(char) (DIGIT - 10 + 'A'));
+ }
+
+ }
+
+
+ /* ------------------------------ GET_NUM ---------------------------------- */
+ /* CURRENT_CHAR points to a string. Starting with the character */
+ /* **CURRENT_CHAR and get the biggest possible integer in BASE NUM_BASE. If */
+ /* that number is too large/small to fit in BITS bits (2's complement), */
+ /* Put an error message into ERROR_REC_BUF. Returns 0 if this or any error is*/
+ /* detected, otherwise it returns the integer representation of the number. */
+ /* NOTE: If number is to large/small this routine stops as soon as it */
+ /* realizes this w/o (with out) looking at the rest of the input. */
+ int GET_NUM(char **CURRENT_CHAR,int BITS,int NUM_BASE)
+ {
+ int CONVERT = 0; /* CONVERT is the converted integer of the */
+ /* string */
+ int MAX_UNSIGNED_INT; /* MAX_UNSIGNED_INT = 2^(BITS-1) */
+ /* - Biggest negative number */
+ /* (w/o sign) that fits */
+ /* - Biggest biggest number + 1 */
+ /* (w/o sign) that fits */
+ int SIGN = 1; /* Sign of the number- assume positive. */
+ char *INPUT_START; /* Keeps track of where string started */
+ int DIGIT; /* One digit of the number. */
+
+ MAX_UNSIGNED_INT = (int) pow(2.0,(BITS-1)*1.0);
+ INPUT_START = *CURRENT_CHAR;
+
+ if ((**CURRENT_CHAR) == '-')
+ SIGN = -1;
+ else SIGN = 1;
+
+ if ( ((**CURRENT_CHAR) == '-') || ((**CURRENT_CHAR) == '+')) {
+ /* ---------------------------- MUST be a valid digit after the sign */
+ (*CURRENT_CHAR) ++;
+ if (CHAR_TO_DIGIT(**CURRENT_CHAR,NUM_BASE) == -1) {
+ char *ERROR_MSG;
+ ERROR_MSG = (char *) malloc((unsigned int) 80);
+ if (**CURRENT_CHAR > 0)
+ (void) sprintf(ERROR_MSG,
+ "eERROR[15]: Illegal Expression. Found '%c' after %c.",
+ **CURRENT_CHAR,*( (*CURRENT_CHAR) - 1));
+ else
+ (void) sprintf(ERROR_MSG,
+ "eERROR[15]: Illegal Expression. Found '' after %c.",
+ *( (*CURRENT_CHAR) - 1));
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ }
+ }
+
+ /* ----------------------------- Get the biggest [legal] number you can */
+ while ( ( (DIGIT = CHAR_TO_DIGIT(**CURRENT_CHAR,NUM_BASE)) != -1) &&
+ !eoln(**CURRENT_CHAR) ) {
+ if (CONVERT <= MAX_UNSIGNED_INT)
+ CONVERT = CONVERT*NUM_BASE + DIGIT;
+ (*CURRENT_CHAR) ++;
+ }
+
+ /* ----------------------------- Make sure number is not to big or small */
+ if ( ((CONVERT > MAX_UNSIGNED_INT) && (SIGN == -1)) ||
+ ((CONVERT > (MAX_UNSIGNED_INT - 1)) && (SIGN == 1)) ) {
+ char SAV_CHAR;
+ char *ERROR_MSG;
+
+ SAV_CHAR = **CURRENT_CHAR;
+ **CURRENT_CHAR = '\0';
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ ((int) log10((double) NUM_BASE)) +
+ ((int) log10((double) MAX_UNSIGNED_INT)) +strlen(INPUT_START)));
+
+ if (SIGN == 1)
+ (void) sprintf(ERROR_MSG,
+ "eERROR[10]: %s[%d] is too large for it's intended use (MAX %d[10]).",
+ INPUT_START,NUM_BASE,MAX_UNSIGNED_INT - 1);
+ else
+ (void) sprintf(ERROR_MSG,
+ "eERROR[11]: %s[%d] is too small for it's intended use (MIN %d[10]).",
+ INPUT_START,NUM_BASE,-1*MAX_UNSIGNED_INT);
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ **CURRENT_CHAR = SAV_CHAR;
+ CONVERT = 0;
+ }
+
+ return CONVERT*SIGN;
+ }
+
+
+ /* ---------------------------- GET_EXPRESSION ----------------------------- */
+ /* Is used to find an expression (well, for now actually it can have no */
+ /* operations, just single terms). Caller can specify what kind of expression*/
+ /* is needed (ABSOLUTE or RELATIVE) or can specify that either kind is okay. */
+ /* Sets WHAT_KIND to they type (kind) of expression found. */
+ int GET_EXPRESSION(char **CURRENT_CHAR,int BITS,int LOCATION,
+ SYMBOL_TABLE *SYM_TAB,int *WHAT_KIND)
+ {
+ char *START; /* remember where the expression */
+ /* started in string. */
+ START = (*CURRENT_CHAR);
+
+ /* ------------------ Check if a decimal constant, if so get it */
+ if ((*WHAT_KIND != RELATIVE_VALUE_1) &&
+ ( ( ((**CURRENT_CHAR) >= '0') && ((**CURRENT_CHAR) <= '9') ) ||
+ ((**CURRENT_CHAR) == '-') || ((**CURRENT_CHAR) == '+') ))
+ {
+ (*WHAT_KIND) = ABSOLUTE_VALUE_1;
+ return GET_NUM(CURRENT_CHAR,BITS,10);
+ }
+
+ /* ------------------ Check if hexidecimal constant, if so, get it */
+ if ((*WHAT_KIND != RELATIVE_VALUE_1) &&
+ ( ((**CURRENT_CHAR) == 'X') && (*((*CURRENT_CHAR)+1) == '\'')) ) {
+ int RESULT;
+
+ (*WHAT_KIND) = ABSOLUTE_VALUE_1;
+ (*CURRENT_CHAR) += 2;
+ RESULT = GET_NUM(CURRENT_CHAR,BITS,16);
+ /* --------------------------- Check for error messages */
+ if ( (**CURRENT_CHAR) != '\'') {
+ while ( (**CURRENT_CHAR != '\'') && (!eoln(**CURRENT_CHAR)) )
+ (*CURRENT_CHAR) ++;
+ if (eoln(**CURRENT_CHAR)) {
+ char ERROR_MSG[80];
+ (void) sprintf(ERROR_MSG,
+ "eERROR[16]: Illegal Hexidecimal. Expected close quote.");
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ } else {
+ char TEMP;
+ char *ERROR_MSG;
+
+ (*CURRENT_CHAR) ++;
+
+ TEMP = **CURRENT_CHAR;
+ **CURRENT_CHAR = '\0';
+
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ strlen(START)));
+
+ (void) sprintf(ERROR_MSG,
+ "eERROR[17]: Illegal Hexidecimal. %s",START);
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ **CURRENT_CHAR = TEMP;
+ }
+ }
+ else (*CURRENT_CHAR) ++;
+ return RESULT;
+ }
+
+ /* ----------------------------- Must be a label, get it */
+ {
+ char LABEL_NAME[LABEL_SIZE_1 + 1];
+ struct SYMBOL_TABLE_ENTRY *LABEL_INFO;
+
+ GET_LABEL(LABEL_NAME,*CURRENT_CHAR,CURRENT_CHAR,pass1);
+
+ if (!strcmp(LABEL_NAME,"")) {
+ /* ----------------------------- There was no label. ERROR */
+ char *ERROR_MSG;
+
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ strlen(*CURRENT_CHAR)));
+ (void) sprintf(ERROR_MSG,
+ "eERROR[14]: Expected an expression, found '%s'.",
+ *CURRENT_CHAR);
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ }
+ else {
+ /* ----------------------------- Get the value of the LABEL */
+ LABEL_INFO = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB);
+ if (LABEL_INFO == NULL) {
+ /* ----------------------------- has no value */
+ char *ERROR_MSG;
+
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ strlen(LABEL_NAME)));
+ if ((*WHAT_KIND) != ABSOLUTE_OR_RELATIVE_1)
+ (void) sprintf(ERROR_MSG,
+ "eERROR[24]: %s is not a defined symbol or is forwardly declared.",
+ LABEL_NAME);
+ else
+ (void) sprintf(ERROR_MSG,"eERROR[49]: %s is not a defined symbol.",
+ LABEL_NAME);
+
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ } else
+ if ( (*WHAT_KIND != RELATIVE_VALUE_1) &&
+ ((*LABEL_INFO).TYPE == ABSOLUTE)) {
+ (*WHAT_KIND) = ABSOLUTE_VALUE_1;
+ return (*LABEL_INFO).LOCATION;
+ } else
+ if ( (*WHAT_KIND != ABSOLUTE_VALUE_1) &&
+ ((*LABEL_INFO).TYPE != ABSOLUTE)) {
+ if ((*LABEL_INFO).TYPE == EXTERN_REF) {
+ /* ----------------------- Value needs a modification record */
+ char OUTPUT_LINE[9+LABEL_SIZE_1];
+ char FIX_LEN_NAME[LABEL_SIZE_1+1];
+ char LEN_STR[3];
+
+ NUM_TO_STR(LOCATION,16,6,OUTPUT_LINE);
+ NUM_TO_STR((BITS/4),16,2,LEN_STR);
+ (void) strcat(OUTPUT_LINE,LEN_STR);
+ (void) strcat(OUTPUT_LINE,"+");
+ BLANK_STR(FIX_LEN_NAME);
+ (void) strncpy(FIX_LEN_NAME,LABEL_NAME,strlen(LABEL_NAME));
+ (void) strcat(OUTPUT_LINE,FIX_LEN_NAME);
+ ADD_TO_END_OF_BUFFER(&MOD_REC_BUF,OUTPUT_LINE);
+ (*WHAT_KIND) = EXTERN_VALUE_1;
+ } else (*WHAT_KIND) = RELATIVE_VALUE_1;
+ return (*LABEL_INFO).LOCATION;
+ } else {
+ char *ERROR_MSG;
+
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ strlen(LABEL_NAME)));
+ if (*WHAT_KIND == ABSOLUTE_VALUE_1)
+ (void) sprintf(ERROR_MSG,
+ "eERROR[25]: %s is a LABEL, expected a CONSTANT.",
+ LABEL_NAME);
+ else
+ (void) sprintf(ERROR_MSG,
+ "eERROR[50]: %s is a CONSTANT, expected a LABEL.",
+ LABEL_NAME);
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+ }
+ }
+ return 0;
+ }
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/convert.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,96 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =============================== convert.h =============================== */
+ /* Contains routines that convert one thing to another. Most of the routines */
+ /* deal with converting a number to a string of that number in some base, or */
+ /* converting a string (assuming some base) into an integer. Basically */
+ /* just a file of miscellaneous 'useful' routines. */
+
+ /* ------------------------ RESET_MISSING_LABEL_NAME ----------------------- */
+ /* No parmeters: */
+ /* Between pass1 and pass2, MISSING_LABEL_NAME must be reset to its */
+ /* orginal value. This procedure does this. */
+ extern void RESET_MISSING_LABEL_NAME();
+
+ /* ------------------------ GET_NEXT_MISSING_LABEL ------------------------- */
+ /* 2 parameters: */
+ /* 1) char *LABEL; String to put label into */
+ /* 2) SYMBOL_TABLE *SYM_TAB; symbol table to insert the label in*/
+ /* Puts MISSING_LABEL_NAME into string LABEL, and puts it into the symbol */
+ /* table. It then changes MISSING_LABEL_NAME to some other unique name. */
+ /* NOTE: this will only return about 90 unique names, after that it returns */
+ /* the same name repeadily. This would result only some additional */
+ /* previously defined label error messages. Never called when executed */
+ /* on a source with no errors. */
+ extern void GET_NEXT_MISSING_LABEL();
+
+ /* ---------------------------- BLANK_STR ---------------------------------- */
+ /* 1 paramter: */
+ /* char *STRING; String to blank out */
+ /* Set characters 0-7 of STRING to blank and make the 8th character NULL */
+ /* ie. a 8 character string of blanks. */
+ extern void BLANK_STR();
+
+ /* ------------------------ CHAR_TO_DIGIT ---------------------------------- */
+ /* 2 parameters: */
+ /* 1) char CH; character to convert */
+ /* 2) int NUM_BASE; base of number */
+ /* Convert a character (CH) into its integer value give base NUM_BASE. Return*/
+ /* -1 if it is not a valid digit in that base. */
+ extern int CHAR_TO_DIGIT();
+
+ /* ------------------------- NUM_TO_STR ------------------------------------ */
+ /* 4 parameters: */
+ /* 1) int NUM; Number to convert */
+ /* 2) int BASE; Base to convert into */
+ /* 3) int LEN; Number of digits in final string */
+ /* 4) char *STR; where to put it. */
+ /* Put into STR the string with LEN digits that represents the number NUM */
+ /* in base BASE (eg. NUM_TO_STR(10,16,3,STR) puts "00A" in STR). */
+ extern void NUM_TO_STR();
+
+ /* -------------------------- PRT_NUM ------------------------------------- */
+ /* 4 parameters: */
+ /* 1) int NUM; Number to print out */
+ /* 2) int NUM_BASE; Base to print it out in */
+ /* 3) int LEN; Number of digits to print out. */
+ /* 4) FILE *OUTPUT; Stream to output the number to */
+ /* Output (to stream OUTPUT) the string with LEN digits that represents the */
+ /* number NUM in base BASE (eg. NUM_TO_STR(20,16,2,STR) puts "14" in STR). */
+ extern void PRT_NUM();
+
+ /* ------------------------------ GET_NUM ---------------------------------- */
+ /* 3 parameters: */
+ /* 1) char **CURRENT_CHAR; pointer to start of string to interpret */
+ /* as an integer (in NUM_BASE) */
+ /* 2) int BITS; Number must fit in this may bits 2's */
+ /* complement. */
+ /* 3) int NUM_BASE; * Base the number is in. */
+ /* CURRENT_CHAR points to a string. Starting with the character */
+ /* **CURRENT_CHAR and get the biggest possible integer in BASE NUM_BASE. If */
+ /* that number is too large/small to fit in BITS bits (2's complement), */
+ /* Put an error message into ERROR_REC_BUF. Returns 0 if this or any error is*/
+ /* detected, otherwise it returns the integer representation of the number. */
+ /* NOTE: If number is to large/small this routine stops as soon as it */
+ /* realizes this w/o (with out) looking at the rest of the input. */
+ extern int GET_NUM();
+
+ /* ---------------------------- GET_EXPRESSION ----------------------------- */
+ /* 5 parameters: */
+ /* 1) char **CURRENT_CHAR; Where to look for the expression */
+ /* 2) int BITS; value of the expression must fit in */
+ /* BITS 2's complement */
+ /* 3) int LOCATION; LOCATION this number is to go into */
+ /* this is needed for modification */
+ /* records when referencing an EXTREF */
+ /* 4) SYMBOL_TABLE *SYM_TAB; The symbol table */
+ /* 5) int *WHAT_KIND; Initially whether the caller wants */
+ /* Relative or absolute or either type */
+ /* of expression. At termination its */
+ /* the kind found. */
+ /* Is used to find an expression (well, for now actually it can have no */
+ /* operations, just single terms). Caller can specify what kind of expression*/
+ /* is needed (ABSOLUTE or RELATIVE) or can specify that either kind is okay. */
+ /* Sets WHAT_KIND to they type (kind) of expression found. */
+ extern int GET_EXPRESSION();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,96 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== op_tab =================================== */
+ /* Defines and allows for loop up in the OPERATOR TABLE */
+ #include <stdio.h>
+ #include "pseudo.h"
+
+ /* ---------------- Possible formats for instructions. */
+ enum formats {ONE,TWO,THREE_FOUR,PSEUDO,NOT_FOUND};
+ /* ---------------- Possible operand types --------------------------------- */
+ enum operands
+ {NONE,REG,REG_REG,MEM,REG_NUM,NUM,PSEUDO_LOC,PSEUDO_NOLOC,PSEUDO_ADDR};
+
+ /* ---------------- Structure of the operator table */
+ struct OP_ENTRY {
+ char *MNEMONIC; /* Name of the operator */
+ enum formats FORMAT; /* FORMAT of this operator */
+ char *OPCODE; /* OPCODE for this operator */
+ enum operands OPERAND; /* Number and type of operands */
+ int FUNCTION; /* Function to execute is PASS1. Pseudo */
+ /* operators only. */
+ };
+
+
+ #define NUM_OPCODES 59 /* number of opcodes in the table */
+ /* NOT counting the NOT_FOUND entry */
+
+ /* table (sorted array) of keywords used in EMITID */
+ struct OP_ENTRY OP_TABLE[] =
+ {{"ADD",THREE_FOUR,"18",MEM,NULL},
+ {"ADDR",TWO,"90",REG_REG,NULL},
+ {"AND",THREE_FOUR,"40",MEM,NULL},
+ {"BYTE",PSEUDO," ",PSEUDO_LOC,PSEUDO_BYTE0},
+ {"CLEAR",TWO,"B4",REG,NULL},
+ {"COMP",THREE_FOUR,"28",MEM,NULL},
+ {"COMPR",TWO,"A0",REG_REG,NULL},
+ {"CSECT",PSEUDO," ",PSEUDO_ADDR,PSEUDO_CSECT0},
+ {"DIV",THREE_FOUR,"24",MEM,NULL}, {"DIVR",TWO,"9C",REG_REG,NULL},
+ {"END",PSEUDO," ",PSEUDO_LOC,PSEUDO_END0},
+ {"EQU",PSEUDO," ",PSEUDO_ADDR,PSEUDO_EQU0},
+ {"EXTDEF",PSEUDO," ",PSEUDO_NOLOC,PSEUDO_EXTDEF0},
+ {"EXTREF",PSEUDO," ",PSEUDO_NOLOC,PSEUDO_EXTREF0},
+ {"HIO",ONE,"F4",NONE,NULL}, {"J",THREE_FOUR,"3C",MEM,NULL},
+ {"JEQ",THREE_FOUR,"30",MEM,NULL}, {"JGT",THREE_FOUR,"34",MEM,NULL},
+ {"JLT",THREE_FOUR,"38",MEM,NULL}, {"JSUB",THREE_FOUR,"48",MEM,NULL},
+ {"LDA",THREE_FOUR,"00",MEM,NULL}, {"LDB",THREE_FOUR,"68",MEM,NULL},
+ {"LDCH",THREE_FOUR,"50",MEM,NULL}, {"LDL",THREE_FOUR,"08",MEM,NULL},
+ {"LDS",THREE_FOUR,"6C",MEM,NULL}, {"LDT",THREE_FOUR,"74",MEM,NULL},
+ {"LDX",THREE_FOUR,"04",MEM,NULL}, {"LPS",THREE_FOUR,"D0",MEM,NULL},
+ {"MUL",THREE_FOUR,"20",MEM,NULL}, {"MULR",TWO,"98",REG_REG,NULL},
+ {"OR",THREE_FOUR,"44",MEM,NULL}, {"RD",THREE_FOUR,"D8",MEM,NULL},
+ {"RESB",PSEUDO," ",PSEUDO_LOC,PSEUDO_RESB0},
+ {"RESW",PSEUDO," ",PSEUDO_LOC,PSEUDO_RESW0},
+ {"RMO",TWO,"AC",REG_REG,NULL}, {"RSUB",THREE_FOUR,"4C",NONE,NULL},
+ {"SHIFTL",TWO,"A4",REG_NUM,NULL}, {"SHIFTR",TWO,"A8",REG_NUM,NULL},
+ {"SIO",ONE,"F0",NONE,NULL}, {"SSK",THREE_FOUR,"EC",MEM,NULL},
+ {"STA",THREE_FOUR,"0C",MEM,NULL},
+ {"START",PSEUDO," ",PSEUDO_ADDR,PSEUDO_START0},
+ {"STB",THREE_FOUR,"78",MEM,NULL}, {"STCH",THREE_FOUR,"54",MEM,NULL},
+ {"STI",THREE_FOUR,"D4",MEM,NULL}, {"STL",THREE_FOUR,"14",MEM,NULL},
+ {"STS",THREE_FOUR,"7C",MEM,NULL}, {"STSW",THREE_FOUR,"E8",MEM,NULL},
+ {"STT",THREE_FOUR,"84",MEM,NULL}, {"STX",THREE_FOUR,"10",MEM,NULL},
+ {"SUB",THREE_FOUR,"1C",MEM,NULL}, {"SUBR",TWO,"94",REG_REG,NULL},
+ {"SVC",TWO,"B0",NUM,NULL}, {"TD",THREE_FOUR,"E0",MEM,NULL},
+ {"TIO",ONE,"F8",NONE,NULL}, {"TIX",THREE_FOUR,"2C",MEM,NULL},
+ {"TIXR",TWO,"B8",REG,NULL}, {"WD",THREE_FOUR,"DC",MEM,NULL},
+ {"WORD",PSEUDO," ",PSEUDO_LOC,PSEUDO_WORD0},
+ /* the next entry must always be last */
+ {"*END OF TABLE*",NOT_FOUND,"00",NONE,NULL}};
+
+
+ /* ---------------------------- LOOK_UP_OP --------------------------------- */
+ /* Find operator in the table. Return the entry if it is found, else return */
+ /* the not found entry. Uses BINARY SEARCH. */
+ struct OP_ENTRY *LOOK_UP_OP(char OP[])
+ {
+ int LOW = 0, /* LOWest element in OP_TABLE that may be the OP */
+ HIGH = NUM_OPCODES-1,/* HIGHest element that may be the OP */
+ MIDDLE; /* (LOW+HIGH)/2... next element considering */
+
+ int CMP; /* stores the result of a string comparison; */
+ /* 0 str1 = str2, 1 str1 > str2, -1 str1 < str2 */
+
+ MIDDLE = 0;
+ while (LOW <= HIGH)
+ {
+ MIDDLE = (HIGH + LOW)/2;
+ if (!(CMP = strcmp(OP_TABLE[MIDDLE].MNEMONIC,OP)))
+ return &OP_TABLE[MIDDLE];
+ if (CMP > 0)
+ HIGH = MIDDLE - 1;
+ else LOW = MIDDLE + 1;
+ }
+ return &OP_TABLE[NUM_OPCODES];
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/op_tab.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,29 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================ op_tab.h =================================== */
+
+ /* ---------------- Possible formats for instructions. */
+ enum formats {ONE,TWO,THREE_FOUR,PSEUDO,NOT_FOUND};
+
+ /* ---------------- Possible operand types --------------------------------- */
+ enum operands
+ {NONE,REG,REG_REG,MEM,REG_NUM,NUM,PSEUDO_LOC,PSEUDO_NOLOC,PSEUDO_ADDR};
+
+ /* ---------------- Structure of the operator table */
+ struct OP_ENTRY {
+ char *MNEMONIC; /* Name of the operator */
+ enum formats FORMAT; /* FORMAT of this operator */
+ char *OPCODE; /* OPCODE for this operator */
+ enum operands OPERAND; /* Number and type of operands */
+ int FUNCTION; /* Function to execute is PASS1. Pseudo */
+ /* operators only. */
+ };
+
+ /* ---------------------------- LOOK_UP_OP --------------------------------- */
+ /* 1 parameter: */
+ /* 1) char OP[]; Name of the OPerator to find. */
+ /* Find operator in the table. Return the entry if it is found, else return */
+ /* the not found entry. Uses BINARY SEARCH. */
+ extern struct OP_ENTRY *LOOK_UP_OP();
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,164 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== pass1.c ================================== */
+ /* Drives pass1 of the assembler, but lets other routines do the real work */
+
+ #include <stdio.h>
+ #include "assem.h"
+ #include "scan_line.h"
+ #include "sym_tab.h"
+ #include "op_tab.h"
+ #include "convert.h"
+ #include "buffer.h"
+ #include "constants.h"
+ #include "pseudo.h"
+
+ #define START_LEGAL_1 0 /* = May see a START legally */
+ #define SEEN_START_1 1 /* = Have seen a START */
+ /* SEND_START_OP Global that contains whether or not */
+ /* a START operator has been seen */
+ int SEEN_START_OP = START_LEGAL_1;
+
+
+ #define NO_END_SEEN_1 0 /* = Haven't seen an END */
+ #define END_SEEN_1 1 /* = Have seen an END but haven't */
+ /* found any code after it */
+ #define END_SEEN_WITH_CODE_1 2 /* = Have seen an END and code after it */
+ #define START_OF_CODE_1 3 /* = Start of code */
+ /* SEEN_END_OP Flag to determine if seen an end since */
+ /* start of last module or not. If so it */
+ /* also indicated if any code seen since */
+ /* end (so only one 'code after end' error */
+ /* is generated. */
+ int SEEN_END_OP = START_OF_CODE_1;
+
+ /* LOCATION_EXCEEDS_MEM_SIZE Indicates if location counter is greater*/
+ /* then the memory size. */
+ int LOCATION_EXCEEDS_MEM_SIZE = FALSE_1;
+
+ /* -------------------------- CHANGE_LOCATION ------------------------------ */
+ /* LOCATION = LOCATION + INCREMENT unless this puts LOCATION past MEM_SIZE, */
+ /* or if the location has already exceeded the memory size. */
+ void CHANGE_LOCATION(int *LOCATION,int INCREMENT,FILE *OUTPUT)
+ {
+ if (!LOCATION_EXCEEDS_MEM_SIZE)
+ if ( ((*LOCATION + INCREMENT) > MEM_SIZE_1) || (*LOCATION == MEM_SIZE_1))
+ {
+ LOCATION_EXCEEDS_MEM_SIZE = TRUE_1;
+ (void) fprintf(OUTPUT,
+ "eERROR[12]: Location exceeds the memory size (%d)\n",
+ MEM_SIZE_1);
+ (*LOCATION) = MEM_SIZE_1 - 1;
+ } else (*LOCATION) += INCREMENT;
+ }
+
+ /* ---------------------- CAPITALIZE_STRING -------------------------------- */
+ /* Make all lower case letters in the string STR upper case letters */
+ void CAPITALIZE_STRING(char STR[])
+ {
+ int I;
+ for (I=0; I<= (strlen(STR)); I++)
+ if ((STR[I] >= 'a') && (STR[I] <= 'z'))
+ STR[I] = STR[I] - 'a' + 'A';
+ }
+
+ /* --------------------------- PASS1 --------------------------------------- */
+ /* Drives the pass1 process, letting others do the real work. */
+ void PASS1(FILE *INPUT_FILE,SYMBOL_TABLE *SYM_TABLE,FILE *TEMP_OUTPUT_STREAM)
+ {
+ char LABEL_NAME[LABEL_SIZE_1+1]; /* Place to store a label. */
+ char OPCODE[LABEL_SIZE_1+1]; /* Place to store an opcode. */
+ char *ARGUMENTS; /* Pointer to arguments/comments */
+ char *INPUT_LINE; /* Pointer to whole source line */
+ int EXTENDED_CODE; /* Boolean: Is this an extended */
+ /* format instruction. */
+
+ int LOCATION_COUNTER =0;
+ MODULE_NAME[0] = '_';
+ MODULE_NAME[1] = '\0';
+
+ (void) INSERT_IN_SYM_TAB(MODULE_NAME,MODULE_NAME,0,RELATIVE,SYM_TABLE);
+
+ MAIN_ROUTINE[0] = '\0';
+ LABEL_NAME[0] = '\0';
+
+ while (!feof(INPUT_FILE)){
+ /* --------------------- Get the source line and do some parsing */
+ SCAN_LINE(LOCATION_COUNTER,&INPUT_LINE,LABEL_NAME,
+ &EXTENDED_CODE,OPCODE,&ARGUMENTS,pass1,
+ TEMP_OUTPUT_STREAM,INPUT_FILE);
+
+ CAPITALIZE_STRING(LABEL_NAME);
+ CAPITALIZE_STRING(OPCODE);
+ CAPITALIZE_STRING(ARGUMENTS);
+
+ if (( strcmp(LABEL_NAME,"") || strcmp(OPCODE,"") || EXTENDED_CODE)
+ && (SEEN_END_OP == END_SEEN_1) && strcmp(OPCODE,"CSECT")
+ && strcmp(OPCODE,"START")) {
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[30]: Statements following END.\n");
+ SEEN_END_OP = END_SEEN_WITH_CODE_1;
+ }
+
+ if (strcmp(LABEL_NAME,""))
+ if ( LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TABLE) == NULL) {
+ CHANGE_LOCATION(&LOCATION_COUNTER,0,TEMP_OUTPUT_STREAM);
+ if (!LOCATION_EXCEEDS_MEM_SIZE)
+ (void) INSERT_IN_SYM_TAB(MODULE_NAME,LABEL_NAME,LOCATION_COUNTER,
+ RELATIVE,SYM_TABLE);
+ }
+ else (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[6]: %s is a multipy defined label.\n",
+ LABEL_NAME);
+
+ if (strcmp(OPCODE,""))
+ {
+ /* --------- Have an OPERATOR. Change location counter depending on format. */
+ struct OP_ENTRY *OPCODE_INFO;
+ switch ( (*(OPCODE_INFO = LOOK_UP_OP(OPCODE))).FORMAT)
+ {
+ case NOT_FOUND: (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[9]: %s is not a legal OPCODE.\n",OPCODE);
+ break;
+ case ONE: CHANGE_LOCATION(&LOCATION_COUNTER,1,TEMP_OUTPUT_STREAM);
+ if (EXTENDED_CODE)
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[8]: + is an illegal prefix to %s.",OPCODE);
+ break;
+ case TWO: CHANGE_LOCATION(&LOCATION_COUNTER,2,TEMP_OUTPUT_STREAM);
+ if (EXTENDED_CODE)
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[8]: + is an illegal prefix to %s.",OPCODE);
+ break;
+ case THREE_FOUR: if (EXTENDED_CODE)
+ CHANGE_LOCATION(&LOCATION_COUNTER,4,TEMP_OUTPUT_STREAM);
+ else CHANGE_LOCATION(&LOCATION_COUNTER,3,TEMP_OUTPUT_STREAM);
+ break;
+ case PSEUDO: if (EXTENDED_CODE)
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[8]: + is an illegal prefix to %s.",OPCODE);
+
+ /* ************************************************************************* */
+ /* The following instruction calls the correct procedure to do what needs to */
+ /* be done for a particular pseudo operator. The operator table contains */
+ /* the pointer to the correct routine. */
+ DO_PSEUDO((*OPCODE_INFO).FUNCTION,LABEL_NAME,ARGUMENTS,
+ &LOCATION_COUNTER,SYM_TABLE,TEMP_OUTPUT_STREAM);
+ break;
+ }
+ }
+
+ if ((SEEN_END_OP == START_OF_CODE_1) &&
+ (strcmp(OPCODE,"") || strcmp(LABEL_NAME,""))) {
+ SEEN_END_OP = NO_END_SEEN_1;
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[35]: No START/CSECT found before statements.\n");
+ }
+ }
+ OUTPUT_BUFFER(&MOD_REC_BUF,TEMP_OUTPUT_STREAM,1);
+ if (!SEEN_END_OP)
+ (void) fprintf(TEMP_OUTPUT_STREAM,
+ "eERROR[36]: End of File detected without an END statement.\n");
+
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass1.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,51 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ================================ pass1.h =============================== */
+
+ #define START_LEGAL_1 0 /* = May see a START legally */
+ #define SEEN_START_1 1 /* = Have seen a START */
+ /* SEND_START_OP Global that contains whether or not */
+ /* a START operator has been seen */
+ extern int SEEN_START_OP;
+
+
+ #define NO_END_SEEN_1 0 /* = Haven't seen an END */
+ #define END_SEEN_1 1 /* = Have seen an END but haven't */
+ /* found any code after it */
+ #define END_SEEN_WITH_CODE_1 2 /* = Have seen an END and code after it */
+ #define START_OF_CODE_1 3 /* = Start of code */
+ /* SEEN_END_OP Flag to determine if seen an end since */
+ /* start of last module or not. If so it */
+ /* also indicated if any code seen since */
+ /* end (so only one 'code after end' error */
+ /* is generated. */
+ extern int SEEN_END_OP;
+
+ /* LOCATION_EXCEEDS_MEM_SIZE Indicates if location counter is greater*/
+ /* then the memory size. */
+ extern int LOCATION_EXCEEDS_MEM_SIZE;
+
+ /* -------------------------- CHANGE_LOCATION ------------------------------ */
+ /* 3 parameters: */
+ /* 1) int *LOCATION; The location counter */
+ /* 2) int INCREMENT; How much to increment it by. */
+ /* 3) FILE *OUTPUT; Where to put error messages, if need be. */
+ /* LOCATION = LOCATION + INCREMENT unless this puts LOCATION past MEM_SIZE, */
+ /* or if the location has already exceeded the memory size. */
+ extern void CHANGE_LOCATION();
+
+ /* ---------------------- CAPITALIZE_STRING -------------------------------- */
+ /* 1 parameter: */
+ /* 1) char STR[]; String to capitalize. */
+ /* Make all lower case letters in the string STR upper case letters */
+ extern void CAPITALIZE_STRING();
+
+ /* --------------------------- PASS1 --------------------------------------- */
+ /* 3 parameters:
+ /* 1) FILE *INPUT_FILE; Stream with the source code */
+ /* 2) SYMBOL_TABLE *SYM_TABLE; The symbol table (already */
+ /* initialized). */
+ /* 3) FILE *TEMP_OUTPUT_STREAM; Stream for the output of Pass1 */
+ /* Drives the pass1 process, letting others do the real work. */
+ extern void PASS1();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,189 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================ pass2.c =================================== */
+ /* Drives the pass2 process, but lets other routines do the real work. */
+ #include <stdio.h>
+ #include <string.h>
+ #include "stringI.h"
+ #include "scan_line.h"
+ #include "convert.h"
+ #include "sym_tab.h"
+ #include "record.h"
+ #include "assem.h"
+ #include "constants.h"
+ #include "buffer.h"
+ #include "code.h"
+
+ /* -------------------------- PASS2 ---------------------------------------- */
+ /* Drives pass2 */
+ void PASS2(FILE *INPUT_STREAM,FILE *OBJECT_STREAM,FILE *LISTING_STREAM,
+ SYMBOL_TABLE *SYM_TAB,int *ERROR)
+ {
+ char TAG_FIELD; /* First character to each line of */
+ /* output is TAG determining what */
+ /* information that line contains. */
+ char *REST_OF_LINE; /* Input line minus the tag field. */
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+ /* Entry in symbol table for a label */
+ char LABEL_NAME[LABEL_SIZE_1+1]; /* Place to store a label. */
+ int ERROR_SINCE_LAST_STATEMENT /* Flag for error detection */
+ = FALSE_1;
+
+ /* --------------------------- Reset module name and NEXT_MISSING_LABEL */
+ /* to their values at the start of pass1 */
+ MODULE_NAME[0] = '_';
+ MODULE_NAME[1] = '\0';
+ RESET_MISSING_LABEL_NAME();
+
+ INITIALIZE_TEXT_RECORD();
+
+ while (!feof(INPUT_STREAM)) {
+ TAG_FIELD = (char) getc(INPUT_STREAM);
+ switch (TAG_FIELD) {
+ case 'p':
+ /* what follows is straight from the source file. Assemble it. */
+ if (ERROR_SINCE_LAST_STATEMENT) (void) fprintf(LISTING_STREAM,"\n");
+ ERROR_SINCE_LAST_STATEMENT = FALSE_1;
+ CODE(INPUT_STREAM,SYM_TAB,OBJECT_STREAM,LISTING_STREAM,
+ &ERROR_SINCE_LAST_STATEMENT);
+ (*ERROR) = ((*ERROR) || ERROR_SINCE_LAST_STATEMENT);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,LISTING_STREAM,2);
+ break;
+
+ case 'e':
+ /* What follows is an error message from pass1. Pass it to listing file. */
+ ERROR_SINCE_LAST_STATEMENT = TRUE_1;
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ (void) fprintf(LISTING_STREAM,"%s\n",REST_OF_LINE);
+ (*ERROR) = TRUE_1;
+ break;
+
+ case 't':
+ {
+ /* What follows is a text record (do to BYTE or WORD) generated in pass1 */
+ /* Handle approperiately. (i.e. Let the text record handler deal with it). */
+ char TEMP_CH;
+ int LOCATION;
+
+ (void) fscanf(INPUT_STREAM,"%d%c",&LOCATION,&TEMP_CH);
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ if ( TEMP_CH == 'W')
+ ADD_TO_TEXT_RECORD(REST_OF_LINE,LOCATION,OBJECT_STREAM);
+ else {
+ char TEMP[HEX_CHAR_PER_BYTE_1+1];
+ int DELTA = 0;
+
+ for (TEMP[HEX_CHAR_PER_BYTE_1]='\0';!eoln(*REST_OF_LINE);
+ REST_OF_LINE+=HEX_CHAR_PER_BYTE_1) {
+ (void) strncpy(TEMP,REST_OF_LINE,HEX_CHAR_PER_BYTE_1);
+ ADD_TO_TEXT_RECORD(TEMP,(LOCATION+DELTA),OBJECT_STREAM);
+ DELTA ++;
+ }
+ }
+ }
+ break;
+
+ case 'E':
+ /* What follows is an end record... pass it and the 'E' to the object file */
+ /* After printing any text records and modification records that may be */
+ /* buffered. */
+ PRT_TEXT_RECORD(OBJECT_STREAM);
+ INITIALIZE_TEXT_RECORD();
+ OUTPUT_BUFFER(&MOD_REC_BUF,OBJECT_STREAM,2);
+
+ if (!strcmp(MAIN_ROUTINE,MODULE_NAME)) {
+ char ADDR[MEM_ADDR_SIZE_1/BITS_PER_HALFBYTE_1+2];
+
+ if (START_ADDRESS == -1)
+ START_ADDRESS = (*LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,
+ SYM_TAB)).LOCATION;
+
+ NUM_TO_STR(START_ADDRESS,16,MEM_ADDR_SIZE_1/BITS_PER_HALFBYTE_1+1,
+ ADDR);
+ (void) fprintf(OBJECT_STREAM,"E%s\n",ADDR);
+ } else (void) fprintf(OBJECT_STREAM,"E\n");
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ break;
+
+ case 'R':
+ /* What follows is a refer record. Pass it and the 'R' to the object file. */
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ (void) fprintf(OBJECT_STREAM,"%c%s\n",TAG_FIELD,REST_OF_LINE);
+ break;
+
+ case 'M':
+ /* What follows is a modification record. Put it on the modification record */
+ /* buffer. */
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ ADD_TO_END_OF_BUFFER(&MOD_REC_BUF,REST_OF_LINE);
+ break;
+
+ case 'd':
+ {
+ /* What follows is a define record. Pass1 didn't know the locations, just */
+ /* the names. It made sure that the the defs will fit in one record though, */
+ /* so here, must just put the locations after the names as output to the */
+ /* object file. */
+ char TEMP[LABEL_SIZE_1+1];
+ int AT;
+
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ (void) fprintf(OBJECT_STREAM,"D");
+
+ for (TEMP[LABEL_SIZE_1]='\0';!eoln(*REST_OF_LINE);
+ REST_OF_LINE+=LABEL_SIZE_1) {
+ (void) strncpy(TEMP,REST_OF_LINE,LABEL_SIZE_1);
+ (void) fprintf(OBJECT_STREAM,"%s",TEMP);
+ for (AT=LABEL_SIZE_1-1;((AT > 0) && (TEMP[AT] == ' '));AT--);
+ TEMP[AT+1] = '\0';
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,TEMP,SYM_TAB);
+
+ if (TABLE_ENTRY == NULL) {
+ (void) fprintf(LISTING_STREAM,
+ "ERROR[41]: %s Undefined label in EXTDEF.\n",
+ TEMP);
+ (void) fprintf(OBJECT_STREAM,"000000");
+ (*ERROR) = 1;
+
+ } else if ((*TABLE_ENTRY).TYPE != RELATIVE) {
+ (void) fprintf(LISTING_STREAM,
+ "ERROR[42]: %s is wrong type. Expected LABEL, found EXTREF or CONSTANT.\n",
+ TEMP);
+ (void) fprintf(OBJECT_STREAM,"000000");
+ (*ERROR) = 1;
+
+ } else PRT_NUM( (*TABLE_ENTRY).LOCATION,16,6,OBJECT_STREAM);
+ }
+ (void) fprintf(OBJECT_STREAM,"\n");
+ }
+ break;
+
+ case 's':
+ /* what follows is a start record. Means must output a Header record to */
+ /* object file. */
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ BLANK_STR(LABEL_NAME);
+ (void) strncpy(LABEL_NAME,REST_OF_LINE,strlen(REST_OF_LINE));
+ (void) strcpy(MODULE_NAME,REST_OF_LINE);
+ (void) fprintf(OBJECT_STREAM,"H%s",LABEL_NAME);
+ TABLE_ENTRY = LOOK_UP_SYMBOL(REST_OF_LINE,REST_OF_LINE,SYM_TAB);
+ PRT_NUM((*TABLE_ENTRY).LOCATION,16,6,OBJECT_STREAM);
+ PRT_NUM((*TABLE_ENTRY).LENGTH,16,6,OBJECT_STREAM);
+ (void) fprintf(OBJECT_STREAM,"\n");
+ break;
+
+ default:
+ /* Something put out by pass1 that shouldn't be here. */
+ if (!feof(INPUT_STREAM)) {
+
+ GET_LINE(&REST_OF_LINE,INPUT_STREAM);
+ (void) printf(
+ "TEMP FILE build incorrectly. This should never happen.\n");
+ (void) printf("%c%s\n",TAG_FIELD,REST_OF_LINE);
+ }
+ break;
+ } /* END switch (TAG_FIELD) */
+ } /* END while (!feof(INPUT_STREAM)) */
+ PRT_TEXT_RECORD(OBJECT_STREAM);
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pass2.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,15 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================ pass2.h =================================== */
+ /* Drives the pass2 process, but lets other routines do the real work. */
+
+ /* -------------------------- PASS2 ---------------------------------------- */
+ /* 5 parameters: */
+ /* 1) FILE *INPUT_STREAM; Input for PASS2 (NOT the source). */
+ /* 2) FILE *OBJECT_STREAM; Stream for the object file. */
+ /* 3) FILE *LISTING_STREAM; Stream for the listing file. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table build in pass1 */
+ /* 5) int *ERROR; ERROR flag. Has an error been seen. */
+ /* Drives pass2 */
+ extern void PASS2();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,515 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================= pseudo.c ================================== */
+ /* Does most of the 'real' work of pass1. Contains the routines for */
+ /* processing each of the pseudo operators. */
+ /* Each of the procedures have the same paramters because they are all called*/
+ /* by the same invocation (by use of a function pointer). Thus may of the */
+ /* procedures have parameters they never use. */
+
+
+ #include <string.h>
+ #include <stdio.h>
+ #include "assem.h"
+ #include "convert.h"
+ #include "sym_tab.h"
+ #include "pass1.h"
+ #include "scan_line.h"
+ #include "record.h"
+ #include "buffer.h"
+ #include "constants.h"
+ #include "pseudo.h"
+
+ /* ------------------------------- PSEUDO_BYTE ----------------------------- */
+ /* Process the BYTE pseudo operator. */
+ void PSEUDO_BYTE(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ char *START; /* Remember where arguments started. */
+ int START_LOC; /* Where the location counter started at */
+ int IS_HEX_Q; /* Is this a HEX (TRUE) or char (FALSE) */
+ /* Initial value. */
+
+ START = ARGUMENTS;
+ START_LOC = *LOCATION;
+
+ if ( (IS_HEX_Q = ( (*ARGUMENTS == 'X') && ( *(ARGUMENTS + 1) = '\'')) ) ||
+ ( (*ARGUMENTS == 'C') && ( *(ARGUMENTS + 1) = '\'')) )
+ {
+ int ERROR = FALSE_1; /* Has an error been found. */
+
+ ARGUMENTS += 2;
+ if (*ARGUMENTS == '\'')
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[18]: Null hexidecimal/character constant.\n");
+ else {
+ int SIZE = 0;
+
+ /* ------- Step through argument till find end or string or end of constant */
+ while ( (!eoln(*ARGUMENTS)) && (*ARGUMENTS != '\'')) {
+ if (IS_HEX_Q) ERROR = (ERROR ||
+ (CHAR_TO_DIGIT(*ARGUMENTS,16) == -1));
+ ARGUMENTS ++;
+ if (!ERROR) SIZE ++;
+ }
+
+ if (ERROR)
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[20]: Illegal hexidecimal.\n");
+
+ if (*ARGUMENTS == '\'') ARGUMENTS ++;
+ else {
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[21]: Illegal hexidecimal/character constant. Missing close quote.\n");
+ ERROR = TRUE_1;
+ }
+
+ if ( IS_HEX_Q && ( (((int) SIZE / 2) * 2) != SIZE)) {
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[22]: Hexidecimal number is not divisible into whole bytes.\n");
+ ERROR = TRUE_1;
+ }
+
+ if (!ERROR) {
+ if (IS_HEX_Q)
+ /* -------- Change location counter to reflect size of BYTE block */
+ CHANGE_LOCATION(LOCATION,(int) SIZE / 2, OUTPUT_STREAM);
+ else CHANGE_LOCATION(LOCATION,SIZE, OUTPUT_STREAM);
+
+ if (IS_HEX_Q) {
+ char TEMP;
+ /* -------- Output text record for BYTE block (hexidecimal) */
+ TEMP = *(ARGUMENTS-1);
+ (*(ARGUMENTS-1)) = '\0';
+ (void) fprintf(OUTPUT_STREAM,"t%dB%s\n",START_LOC,(START+2));
+ (*(ARGUMENTS-1)) = TEMP;
+ } else {
+ /* -------- Output text record for BYTE block (character) */
+ char *LOOP;
+
+ (void) fprintf(OUTPUT_STREAM,"t%dB",START_LOC);
+ for (LOOP = START + 2; LOOP <= ARGUMENTS - 2; LOOP ++)
+ PRT_NUM((int) *LOOP,16,2,OUTPUT_STREAM);
+ (void) fprintf(OUTPUT_STREAM,"\n");
+ }
+ }
+ if (!IS_BLANK_OR_TAB(*ARGUMENTS) && !eoln(*ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *ARGUMENTS);
+ }
+ } else
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[19]: Expected hexidecimal or character constant.\n");
+ }
+
+ /* --------------------------- PSEUDO_CSECT -------------------------------- */
+ /* Process the CSECT pseudo operator. */
+ void PSEUDO_CSECT(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+
+ if (!SEEN_END_OP) {
+ /* --------- If haven't seen an end, then pretend you did. */
+ (void) fprintf(OUTPUT_STREAM,"eERROR[27]: Section %s has no 'end'.\n",
+ MODULE_NAME);
+ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1);
+ LOCATION_EXCEEDS_MEM_SIZE = 0;
+ (void) fprintf(OUTPUT_STREAM,"E\n");
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB);
+ (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION;
+ }
+
+ SEEN_END_OP = NO_END_SEEN_1;
+
+ if (!strcmp(LABEL_NAME,"")) {
+ (void) fprintf(OUTPUT_STREAM,"eERROR[26]: CSECT requires a label.\n");
+ GET_NEXT_MISSING_LABEL(LABEL_NAME,SYM_TAB);
+ }
+
+ if (LOOK_UP_SYMBOL(LABEL_NAME,LABEL_NAME,SYM_TAB) != NULL) {
+ (void) fprintf(OUTPUT_STREAM,"eERROR[55]: Multiply defined module name.\n");
+ (void) strcpy(MODULE_NAME,LABEL_NAME);
+ } else {
+ /* --------------- Update symbol to reflect fact that LABEL_NAME is a module */
+ /* name. */
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB);
+ (*TABLE_ENTRY).LOCATION = 0;
+ (void) strcpy( (*TABLE_ENTRY).MODULE, LABEL_NAME);
+ (void) strcpy(MODULE_NAME,LABEL_NAME);
+
+ /* ---------------- Reset location counter to zero */
+ (*LOCATION) = 0;
+ (void) fprintf(OUTPUT_STREAM,"s%s\n",MODULE_NAME);
+ }
+ }
+
+ /* --------------------------- PSEUDO_END ---------------------------------- */
+ /* Process the END pseudo operator. */
+ void PSEUDO_END(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+
+ SEEN_END_OP = END_SEEN_1;
+
+ if (strcmp(ARGUMENTS,""))
+ {
+ char OPERAND_LAB[LABEL_SIZE_1+1];
+ char *START;
+ START = ARGUMENTS;
+
+ GET_LABEL(OPERAND_LAB,ARGUMENTS,&START,pass1);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+
+ if (strcmp(OPERAND_LAB,"")) {
+ /* ----------- End specifies a start adress. */
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MAIN_ROUTINE,OPERAND_LAB,SYM_TAB);
+
+ if (TABLE_ENTRY == NULL)
+ (void) fprintf(OUTPUT_STREAM,"eERROR[28]: Label %s not defined.\n",
+ OPERAND_LAB);
+ else if ((*TABLE_ENTRY).TYPE == ABSOLUTE)
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[28]: Expected label, found constant %s.\n",
+ OPERAND_LAB);
+ else {
+ /* ---------------- Found an valid end statement. Clear modify buffer. */
+ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1);
+ LOCATION_EXCEEDS_MEM_SIZE = 0;
+ (void) fprintf(OUTPUT_STREAM,"E\n");
+ if (START_ADDRESS == -1)
+ START_ADDRESS = (*TABLE_ENTRY).LOCATION;
+ else
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[54]: Multiple starting addresses. Using first.\n");
+ }
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+ } else (void) fprintf(OUTPUT_STREAM,
+ "eERROR[31]: Expected a Symbol, found %s.\n",
+ ARGUMENTS);
+
+ } else {
+ /* ------------------ End doesn't specify a start address */
+ /* Clear modify buffer */
+ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1);
+ LOCATION_EXCEEDS_MEM_SIZE = 0;
+ (void) fprintf(OUTPUT_STREAM,"E\n");
+ }
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB);
+ (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION;
+ (void) strcpy(MODULE_NAME,"_");
+ (*LOCATION) = 0;
+ }
+
+ /* --------------------------- PSEUDO_EQU ---------------------------------- */
+ /* Process the EQU pseudo operator. */
+ void PSEUDO_EQU(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ if (!strcmp(LABEL_NAME,""))
+ (void) fprintf(OUTPUT_STREAM,"eERROR[23]: EQU requires a label.\n");
+ else {
+ char *START;
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+ int ABS_VAL = ABSOLUTE_VALUE_1;
+
+ START = ARGUMENTS;
+
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB);
+
+ (*TABLE_ENTRY).LOCATION =
+ GET_EXPRESSION(&START,MEM_ADDR_SIZE_1+1,*LOCATION,SYM_TAB,&ABS_VAL);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+ (*TABLE_ENTRY).TYPE = ABSOLUTE;
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+ }
+
+ }
+
+ /* --------------------------- PSEUDO_EXTDEF ------------------------------- */
+ /* Process the EXTDEF pseudo operator. */
+ void PSEUDO_EXTDEF(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ char *START;
+ char DEF_LAB[LABEL_SIZE_1+1];
+ int ERROR = FALSE_1;
+ char TEMP[LABEL_SIZE_1+1];
+
+ if (!strcmp(ARGUMENTS,""))
+ (void) fprintf(OUTPUT_STREAM,"eERROR[40]: EXTDEF requires arguments.\n");
+ else {
+ START = ARGUMENTS;
+ INITIALIZE_RECORD("d",LABEL_SIZE_1*5+1);
+
+ /* ------------------ Get the list of label names put in a record buffer */
+ do {
+ ARGUMENTS = START;
+ GET_LABEL(DEF_LAB,START,&START,pass1);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+
+ if (!strcmp(DEF_LAB,"")) ERROR = TRUE_1;
+ else {
+ BLANK_STR(TEMP);
+ (void) strncpy(TEMP,DEF_LAB,strlen(DEF_LAB));
+ ADD_TO_RECORD(TEMP,OUTPUT_STREAM);
+ }
+ START ++;
+ } while (!ERROR && ((*(START-1)) == ','));
+
+ /* ------------------- Output the define record */
+ PRT_RECORD(OUTPUT_STREAM);
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && !ERROR &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *(START-1));
+
+ if (ERROR == 1)
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[39]: Invalid list of symbols. Expected symbol found %s.\n",
+ ARGUMENTS);
+ }
+ }
+
+ /* --------------------------- PSEUDO_EXTREF ------------------------------- */
+ /* Process the EXTREF pseudo operator. */
+ void PSEUDO_EXTREF(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ char *START;
+ char DEF_LAB[LABEL_SIZE_1+1];
+ int ERROR = FALSE_1;
+ char TEMP[LABEL_SIZE_1+1];
+
+ if (!strcmp(ARGUMENTS,""))
+ (void) fprintf(OUTPUT_STREAM,"eERROR[37]: EXTREF requires arguments.\n");
+ else {
+ START = ARGUMENTS;
+ INITIALIZE_RECORD("R",LABEL_SIZE_1*9+1);
+
+ /* ----------------------------- Get the list of labels that are externally */
+ /* defined. Buffer them. */
+ do {
+ ARGUMENTS = START;
+ GET_LABEL(DEF_LAB,START,&START,pass1);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+ if (!strcmp(DEF_LAB,"")) ERROR = 1;
+ else if (!INSERT_IN_SYM_TAB(MODULE_NAME,DEF_LAB,0,EXTERN_REF,SYM_TAB))
+ ERROR = 2;
+ else {
+ BLANK_STR(TEMP);
+ (void) strncpy(TEMP,DEF_LAB,strlen(DEF_LAB));
+ ADD_TO_RECORD(TEMP,OUTPUT_STREAM);
+ }
+ START ++;
+ } while (!ERROR && ((*(START-1)) == ','));
+
+ PRT_RECORD(OUTPUT_STREAM);
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) && !ERROR &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *(START-1));
+
+ if (ERROR == 1)
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[39]: Invalid list of symbols. Expected symbol found %s.\n",
+ ARGUMENTS);
+ if (ERROR == 2) {
+ *(START-1) = '\0';
+ (void) fprintf(OUTPUT_STREAM,"eERROR[38]: %s is already defined.\n",
+ ARGUMENTS);
+ }
+
+ }
+ }
+
+ /* --------------------------- PSEUDO_RESB --------------------------------- */
+ /* Process the RESB pseudo operator. */
+ void PSEUDO_RESB(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ char *START;
+ int ABS_VAL = ABSOLUTE_VALUE_1;
+
+ START = ARGUMENTS;
+
+ CHANGE_LOCATION(LOCATION,
+ GET_EXPRESSION(&START,MEM_ADDR_SIZE_1+1,*LOCATION,SYM_TAB,&ABS_VAL),
+ OUTPUT_STREAM);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+ }
+
+ /* --------------------------- PSEUDO_RESW --------------------------------- */
+ /* Process the RESW pseudo operator. */
+ void PSEUDO_RESW(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ char *START;
+ int ABS_VAL = ABSOLUTE_VALUE_1;
+
+ START = ARGUMENTS;
+
+ CHANGE_LOCATION(LOCATION,
+ GET_EXPRESSION(&START,MEM_ADDR_SIZE_1,*LOCATION,SYM_TAB,&ABS_VAL)*3,
+ OUTPUT_STREAM);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+ }
+
+ /* --------------------------- PSEUDO_START =------------------------------- */
+ /* Process the START pseudo operator. */
+ void PSEUDO_START(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+ int VALUE;
+ char *START;
+
+ if (!SEEN_END_OP) {
+ (void) fprintf(OUTPUT_STREAM,"eERROR[27]: Section %s has no 'end'.\n",
+ MODULE_NAME);
+ OUTPUT_BUFFER(&MOD_REC_BUF,OUTPUT_STREAM,1);
+ LOCATION_EXCEEDS_MEM_SIZE = 0;
+ (void) fprintf(OUTPUT_STREAM,"E\n");
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,MODULE_NAME,SYM_TAB);
+ (*TABLE_ENTRY).LENGTH = (*LOCATION) - (*TABLE_ENTRY).LOCATION;
+ }
+ if (SEEN_START_OP == SEEN_START_1)
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[32]: Multiple STARTs in this file.\n");
+
+ SEEN_START_OP = SEEN_START_1;
+ SEEN_END_OP = NO_END_SEEN_1;
+
+ if (!strcmp(LABEL_NAME,"")) {
+ (void) fprintf(OUTPUT_STREAM,"eERROR[33]: START requires a label.\n");
+ GET_NEXT_MISSING_LABEL(LABEL_NAME,SYM_TAB);
+ }
+
+ if (LOOK_UP_SYMBOL(LABEL_NAME,LABEL_NAME,SYM_TAB) != NULL) {
+ (void) fprintf(OUTPUT_STREAM,"eERROR[55]: Multiply defined module name.\n");
+ (void) strcpy(MODULE_NAME,LABEL_NAME);
+ } else {
+ /* --------------- Modify LABEL_NAMEs symbol table entry to reflect that it */
+ /* is a module name. */
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE_NAME,LABEL_NAME,SYM_TAB);
+ START = ARGUMENTS;
+ VALUE = GET_NUM(&START,MEM_ADDR_SIZE_1+1,10);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+
+ if (VALUE < 0)
+ (void) fprintf(OUTPUT_STREAM,"eERROR[34]: Negative starting address.\n");
+ else (*TABLE_ENTRY).LOCATION = VALUE;
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+
+ /* ---------------- Indicate that is a module and the MAIN module. */
+ (void) strcpy( (*TABLE_ENTRY).MODULE, LABEL_NAME);
+ (void) strcpy(MODULE_NAME,LABEL_NAME);
+ (void) strcpy(MAIN_ROUTINE,LABEL_NAME);
+
+ (*LOCATION) = (*TABLE_ENTRY).LOCATION;
+ (void) fprintf(OUTPUT_STREAM,"s%s\n",MODULE_NAME);
+ }
+ }
+
+ /* --------------------------- PSEUDO_WORD --------------------------------- */
+ /* Process the WORD pseudo operator. */
+ void PSEUDO_WORD(char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ int VALUE;
+ char *START;
+ int ABS_VAL = ABSOLUTE_VALUE_1;
+
+ START = ARGUMENTS;
+
+ VALUE = GET_EXPRESSION(&START,BITS_PER_WORD_1,*LOCATION,
+ SYM_TAB,&ABS_VAL);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,OUTPUT_STREAM,1);
+
+ (void) fprintf(OUTPUT_STREAM,"t%dW",*LOCATION);
+ PRT_NUM(VALUE,16,6,OUTPUT_STREAM);
+ (void) fprintf(OUTPUT_STREAM,"\n");
+
+ CHANGE_LOCATION(LOCATION,3, OUTPUT_STREAM);
+
+ if (!IS_BLANK_OR_TAB(*START) && !eoln(*START) &&
+ (START != ARGUMENTS))
+ (void) fprintf(OUTPUT_STREAM,
+ "eERROR[13]: Expected a <space> after the operand, found %c.\n",
+ *START);
+ }
+
+ /* ---------------------------- DO_PSEUDO ---------------------------------- */
+ /* execute a pseudo function */
+ void DO_PSEUDO(int WHICH_PSEUDO,char *LABEL_NAME,char *ARGUMENTS,int *LOCATION,
+ SYMBOL_TABLE *SYM_TAB,FILE *OUTPUT_STREAM)
+ {
+ switch (WHICH_PSEUDO) {
+ case PSEUDO_BYTE0:
+ PSEUDO_BYTE(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_CSECT0:
+ PSEUDO_CSECT(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_END0:
+ PSEUDO_END(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_EQU0:
+ PSEUDO_EQU(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_EXTDEF0:
+ PSEUDO_EXTDEF(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_EXTREF0:
+ PSEUDO_EXTREF(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_RESB0:
+ PSEUDO_RESB(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_RESW0:
+ PSEUDO_RESW(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_START0:
+ PSEUDO_START(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ case PSEUDO_WORD0:
+ PSEUDO_WORD(LABEL_NAME,ARGUMENTS,LOCATION,SYM_TAB,OUTPUT_STREAM);
+ break;
+ default: break;
+ }
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/pseudo.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,144 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== pseudo.h ================================= */
+ /* Does most of the 'real' work of pass1. Contains the routines for */
+ /* processing each of the pseudo operators. */
+ /* Each of the procedures have the same paramters because they are all called*/
+ /* by the same invocation (by use of a function pointer). Thus may of the */
+ /* procedures have parameters they never use. */
+
+ /* ------------------------------- PSEUDO_BYTE ----------------------------- */
+ /* 5 parameters: */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* ************** SYMB_TAB not used */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the BYTE pseudo operator. */
+ extern void PSEUDO_BYTE();
+ #define PSEUDO_BYTE0 1
+
+ /* --------------------------- PSEUDO_CSECT -------------------------------- */
+ /* 5 parameters: */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* ************** ARGUMENTS not used */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the CSECT pseudo operator. */
+ extern void PSEUDO_CSECT();
+ #define PSEUDO_CSECT0 2
+
+ /* --------------------------- PSEUDO_END ---------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the END pseudo operator. */
+ extern void PSEUDO_END();
+ #define PSEUDO_END0 3
+
+ /* --------------------------- PSEUDO_EQU ---------------------------------- */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the EQU pseudo operator. */
+ extern void PSEUDO_EQU();
+ #define PSEUDO_EQU0 4
+
+ /* --------------------------- PSEUDO_EXTDEF ------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* ************** LOCATION not used */
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* ************** SYM_TAB not used */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the EXTDEF pseudo operator. */
+ extern void PSEUDO_EXTDEF();
+ #define PSEUDO_EXTDEF0 5
+
+ /* --------------------------- PSEUDO_EXTREF ------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* ************** LOCATION not used */
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the EXTREF pseudo operator. */
+ extern void PSEUDO_EXTREF();
+ #define PSEUDO_EXTREF0 6
+
+ /* --------------------------- PSEUDO_RESB --------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the RESB pseudo operator. */
+ extern void PSEUDO_RESB();
+ #define PSEUDO_RESB0 7
+
+ /* --------------------------- PSEUDO_RESW --------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the RESW pseudo operator. */
+ extern void PSEUDO_RESW();
+ #define PSEUDO_RESW0 8
+
+ /* --------------------------- PSEUDO_START =------------------------------- */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the START pseudo operator. */
+ extern void PSEUDO_START();
+ #define PSEUDO_START0 9
+
+ /* --------------------------- PSEUDO_WORD --------------------------------- */
+ /* ************** LABEL_NAME not used */
+ /* 1) char *LABEL_NAME; LABEL found on source line. */
+ /* 2) char *ARGUMENTS; Everything after the operand in source*/
+ /* 3) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 4) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 5) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* Process the WORD pseudo operator. */
+ extern void PSEUDO_WORD();
+ #define PSEUDO_WORD0 10
+
+ /* ---------------------------- DO_PSEUDO ---------------------------------- */
+ /* 1) int WHICH_PSEUDO; Which pseudo func to execute. */
+ /* 2) char *LABEL_NAME; LABEL found on source line. */
+ /* 3) char *ARGUMENTS; Everything after the operand in source*/
+ /* 4) int *LOCATION; What location counter was when this */
+ /* line of source was found. */
+ /* 5) SYMBOL_TABLE *SYM_TAB; Symbol table */
+ /* 6) FILE *OUTPUT_STREAM; Stream for the output. */
+ /* execute a pseudo function */
+ extern void DO_PSEUDO();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,145 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =============================== record.c ================================ */
+ /* This is another buffering module, but unlike buffer.c that buffers whole */
+ /* lines of code and whole records, this buffers pieces of one record. A */
+ /* object record has an maximal size and contains as much information on */
+ /* one record as it possibly can (it tries to use 1 record instead of 2, if */
+ /* possible). This routine allows other routines to say, 'This belongs in a */
+ /* record, take care of it'. And it descides when to start a new record and */
+ /* when not put it on the current record. */
+ #include <stdio.h>
+ #include <string.h>
+ #include "convert.h"
+ #include "constants.h"
+
+ /* MAX_RECORD_SIZE_1 Largest size of ANY record. */
+ #define MAX_RECORD_SIZE_1 80
+
+ char RECORD[MAX_RECORD_SIZE_1 + 1]; /* The current record creating */
+ char INIT_RECORD[MAX_RECORD_SIZE_1 + 1]; /* The intial configuration */
+ int NEXT_COL; /* Where the next thing will go into*/
+ /* the record. */
+ int MAX_SIZE; /* The maximum size of THIS record */
+ int LOCATION = 0; /* Where in SICs main memory does */
+ /* this record start. Only TEXT */
+ /* records. */
+
+ /* IS_INITIALIZED Has the record been initialized? */
+ #define NOT_INIT_2 0
+ #define INITIALIZED_2 1
+ int IS_INITIALIZED = NOT_INIT_2;
+
+ /* --------------------------- INITIALIZE_RECORD --------------------------- */
+ /* Set up all the global variables needed to handle records. */
+ void INITIALIZE_RECORD(char *VAL,int SIZE)
+ {
+ if ((SIZE > MAX_RECORD_SIZE_1) || (strlen(VAL) > SIZE) || IS_INITIALIZED)
+ (void) printf("INITIALIZE_RECORD called illegally.\n");
+ else {
+ (void) strcpy(INIT_RECORD,VAL);
+ (void) strcpy(RECORD,VAL);
+ MAX_SIZE = SIZE;
+ NEXT_COL = strlen(RECORD);
+ IS_INITIALIZED = INITIALIZED_2;
+ }
+ }
+
+ /* ------------------------- PRT_RECORD ------------------------------------ */
+ /* If anything is in the record, output it. Set the record to unitialized. */
+ void PRT_RECORD(FILE *OUTPUT)
+ {
+ if (!IS_INITIALIZED)
+ (void) printf("PRT_RECORD called illegally.\n");
+ else {
+ if (strcmp(RECORD,INIT_RECORD))
+ (void) fprintf(OUTPUT,"%s\n",RECORD);
+ IS_INITIALIZED = NOT_INIT_2;
+ }
+ }
+
+ /* ------------------------- ADD_TO_RECORD --------------------------------- */
+ /* Put Value into the record. If the record needs to be output put it into */
+ /* stream OUTPUT. */
+ void ADD_TO_RECORD(char *VAL,FILE *OUTPUT)
+ {
+ int LENGTH; /* Stores legth of the record */
+ int ERROR = FALSE_1; /* Has an error been detected. */
+
+ if (!IS_INITIALIZED) ERROR = 1;
+ else
+ if ((NEXT_COL + (LENGTH = strlen(VAL))) > MAX_SIZE) {
+ /* ---------- Output current record, but VAL onto next record. */
+ PRT_RECORD(OUTPUT);
+ INITIALIZE_RECORD(INIT_RECORD,MAX_SIZE);
+ if ((NEXT_COL + LENGTH) > MAX_SIZE)
+ ERROR = 1;
+ }
+ if (!ERROR) {
+ (void) strcpy(&(RECORD[NEXT_COL]),VAL);
+ NEXT_COL += LENGTH;
+ } else
+ (void) printf("ADD_TO_RECORD called illegally.\n");
+ }
+
+ /* --------------------- INITITIALIZE_TEXT_RECORD -------------------------- */
+ /* Initialize a special type of record. A text record. */
+ void INITIALIZE_TEXT_RECORD(void)
+ {
+ /* Normal record contains col. 10-69 of text record. */
+ INITIALIZE_RECORD("",60);
+ }
+
+ /* ---------------------- PRT_TEXT_RECORD ---------------------------------- */
+ /* If anything is in the text record, output it. Set the record to */
+ /* unitialized. */
+ void PRT_TEXT_RECORD(FILE *OUTPUT)
+ {
+ if (!IS_INITIALIZED)
+ (void) printf("PRT_TEXT_RECORD called illegally.\n");
+ else {
+ if (strcmp(RECORD,INIT_RECORD)) {
+ (void) fprintf(OUTPUT,"T");
+ PRT_NUM(LOCATION,16,6,OUTPUT);
+ PRT_NUM((NEXT_COL/HEX_CHAR_PER_BYTE_1),16,2,OUTPUT);
+ (void) fprintf(OUTPUT,"%s\n",RECORD);
+
+ }
+ IS_INITIALIZED = NOT_INIT_2;
+ }
+ }
+
+ /* ------------------------- ADD_TO_TEXT_RECORD ---------------------------- */
+ /* Put Value into the text record at SIC addres PUT_AT. If the record needs */
+ /* to be output put it into stream OUTPUT. Record must be output if the */
+ /* current record is full, or where the VALUE belongs isn't the next spot */
+ /* on the text record. */
+ void ADD_TO_TEXT_RECORD(char *VAL,int PUT_AT,FILE *OUTPUT)
+ {
+ int ERROR = FALSE_1;
+ int LEN;
+
+ LEN = strlen(VAL);
+
+ if (!IS_INITIALIZED || (LEN > MAX_SIZE)) ERROR = 1;
+ else {
+
+ if (!ERROR && ((LOCATION + NEXT_COL/HEX_CHAR_PER_BYTE_1) != PUT_AT) ) {
+ PRT_TEXT_RECORD(OUTPUT);
+ LOCATION = PUT_AT;
+ INITIALIZE_TEXT_RECORD();
+ }
+
+ if (!ERROR && ((NEXT_COL + LEN) > MAX_SIZE) ) {
+ PRT_TEXT_RECORD(OUTPUT);
+ LOCATION += strlen(RECORD)/HEX_CHAR_PER_BYTE_1;
+ INITIALIZE_TEXT_RECORD();
+ }
+ }
+ if (!ERROR) {
+ (void) strcpy(&(RECORD[NEXT_COL]),VAL);
+ NEXT_COL += LEN;
+ } else
+ (void) printf("ADD_TO_TEXT_RECORD called illegally.\n");
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/record.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,57 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ============================== record.h ================================= */
+ /* This is another buffering module, but unlike buffer.c that buffers whole */
+ /* lines of code and whole records, this buffers pieces of one record. A */
+ /* object record has an maximal size and contains as much information on */
+ /* one record as it possibly can (it tries to use 1 record instead of 2, if */
+ /* possible). This routine allows other routines to say, 'This belongs in a */
+ /* record, take care of it'. And it descides when to start a new record and */
+ /* when not put it on the current record. */
+
+ /* --------------------------- INITIALIZE_RECORD --------------------------- */
+ /* 2 parameters: */
+ /* 1) char *VAL; Intial value/header of a record */
+ /* eg. "R" for a reference record. */
+ /* 2) int SIZE; Biggest this type of record can ever */
+ /* get. */
+ /* Set up all the global variables needed to handle records. */
+ extern void INITIALIZE_RECORD();
+
+ /* ------------------------- PRT_RECORD ------------------------------------ */
+ /* 1 parameters: */
+ /* 1) FILE *OUTPUT; Stream to output the record to */
+ /* If anything is in the record, output it. Set the record to unitialized. */
+ extern void PRT_RECORD();
+
+ /* ------------------------- ADD_TO_RECORD --------------------------------- */
+ /* Put Value into the record. If the record needs to be output put it into */
+ /* 2 parameters: */
+ /* 1) char *VAL; /* Value to add to the record */
+ /* 2) FILE *OUTPUT; /* If need be, where to output the record*/
+ /* stream OUTPUT. */
+
+ extern void ADD_TO_RECORD();
+
+ /* --------------------- INITITIALIZE_TEXT_RECORD -------------------------- */
+ /* No parameters */
+ /* Initialize a special type of record. A text record. */
+ extern void INITIALIZE_TEXT_RECORD();
+
+ /* ---------------------- PRT_TEXT_RECORD ---------------------------------- */
+ /* 1 parameter:
+ /* 1) FILE *OUTPUT; /* Stream to output the record to */
+ /* If anything is in the text record, output it. Set the record to */
+ /* unitialized. */
+ extern void PRT_TEXT_RECORD();
+
+ /* ------------------------- ADD_TO_TEXT_RECORD ---------------------------- */
+ /* 1) char *VAL; /* Value to add to text record */
+ /* 2) int PUT_AT; /* Location in SIC the value will go into */
+ /* 3) FILE *OUTPUT; /* If need to OUTPUT, put it into stream */
+ /* Put Value into the text record at SIC addres PUT_AT. If the record needs */
+ /* to be output put it into stream OUTPUT. Record must be output if the */
+ /* current record is full, or where the VALUE belongs isn't the next spot */
+ /* on the text record. */
+ extern void ADD_TO_TEXT_RECORD();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,217 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ================================ scan_line.c ============================ */
+ /* Contains routines for doing simple parsing of source program (eg. return */
+ /* label, operator and everthing after the operator). */
+ #include <stdio.h>
+ #include <math.h>
+ #include <string.h>
+ #include <malloc.h>
+ #include "stringI.h"
+ #include "assem.h"
+ #include "buffer.h"
+ #include "constants.h"
+
+ /* pass_type Which pass the assembler is currently in. Used to */
+ /* surpress redisplaying pass1 error messages in */
+ /* pass2. */
+ enum pass_type {pass1,pass2};
+
+ /* ----------------------------- UPPER (local) ----------------------------- */
+ /* If CH is a lower case letter, return the upper case version, otherwise */
+ /* Return the character. */
+ char UPPER(CH)
+ char CH; /* Character to convert to upper case (if needed). */
+ {
+ if ((CH >= 'a') && (CH <= 'z')) return (CH - 'a' + 'A');
+ else return CH;
+ }
+
+ /* ------------------------------ IS_ALPHA_NUM ----------------------------- */
+ /* True if CH is a capital letter or a digit. Otherwise false. */
+ int IS_ALPHA_NUM(CH)
+ char CH; /* Character in question. */
+ {
+ CH = UPPER(CH);
+ return ( ((CH >= 'A') && (CH <= 'Z')) || ((CH >= '0') && (CH <= '9')) );
+ }
+
+ /* ------------------------------ IS_BLANK_OR_TAB -------------------------- */
+ /* True if CH is a blank or a tab, otherwise false. */
+ int IS_BLANK_OR_TAB(CH)
+ char CH; /* Character in question. */
+ {
+ return ((CH == ' ' /* Blank */) || (CH == ' ' /* TAB */));
+ }
+
+ /* ----------------------------- eoln -------------------------------------- */
+ /* true if CH is the End Of LiNe character, otherwise false. */
+ int eoln(CH)
+ char CH; /* Character in question. */
+ {
+ return (CH == '\0');
+ }
+
+ /* -------------------------------- GET_LABEL ------------------------------ */
+ /* Get a SIC/XE Label (Letter followed by zero to seven letters or digits). */
+ /* Return it in LABEL. Get it from INPUT starting from NEXT_CHAR. */
+ void GET_LABEL (LABEL,INPUT,NEXT_CHAR,PASS)
+ char *LABEL; /* Where to put the label if found. */
+ char *INPUT; /* String to get the label from. */
+ enum pass_type PASS; /* pass1 = buffers error messages in ERROR_REC_BUF*/
+ /* pass2 = don't buffer error messages. */
+ char **NEXT_CHAR; /* where to start looking for the label in INPUT */
+ {
+ if ((UPPER(**NEXT_CHAR) >= 'A') && (UPPER(**NEXT_CHAR) <= 'Z')) {
+
+ /* GET LABEL */
+ int LABEL_LEN = 1;
+ (*NEXT_CHAR) ++;
+ while (IS_ALPHA_NUM(**NEXT_CHAR) && (!eoln(**NEXT_CHAR))) {
+ LABEL_LEN ++;
+ (*NEXT_CHAR) ++;
+ };
+ if (LABEL_LEN > LABEL_SIZE_1) {
+ if (PASS == pass1) {
+ char TEMP;
+ char *ERROR_MSG;
+
+ TEMP = INPUT[LABEL_LEN];
+ INPUT[LABEL_LEN] = '\0';
+
+ ERROR_MSG = (char *) malloc((unsigned int)
+ (80+ ((int) log10((double) LABEL_SIZE_1)) +strlen(INPUT)));
+ (void) sprintf(ERROR_MSG,
+ "eERROR[1]: Label '%s' is too long (MAX %d characters).",
+ INPUT,LABEL_SIZE_1);
+ ADD_TO_END_OF_BUFFER(&ERROR_REC_BUF,ERROR_MSG);
+ free(ERROR_MSG);
+
+ INPUT[LABEL_LEN] = TEMP;
+ };
+ /* ------------------- truncate to 8 characters. */
+ LABEL_LEN = LABEL_SIZE_1;
+ };
+ (void) strncpy(LABEL,INPUT,LABEL_LEN);
+ LABEL[LABEL_LEN] = '\0';
+ /* End GET LABEL */
+ } else {
+ /* ---------- Object Starting at NEXT_CHAR can not possible be a label */
+ /* Return the empty string ("") */
+ LABEL[0] = '\0';
+ }
+ }
+
+ /* ------------------------- GET_OPCODE_STR -------------------------------- */
+ /* Get a SIC/XE OPERAND (string of letters, not more than 8).Return it in */
+ /* OPCODE. Get it from INPUT starting from NEXT_CHAR. */
+ void GET_OPCODE_STR (OPCODE,NEXT_CHAR,PASS,STREAM)
+ char *OPCODE; /* Where to put the opcode that was found. */
+ enum pass_type PASS; /* pass1 = print error messages; pass2 = don't*/
+ /* print error messages. */
+ char **NEXT_CHAR; /* Where to look for the OPERAND */
+ FILE *STREAM; /* Stream to output error messages to. */
+ {
+ char *START_OF_OPCODE;
+ START_OF_OPCODE = *NEXT_CHAR;
+ if ((UPPER(**NEXT_CHAR) >= 'A') && (UPPER(**NEXT_CHAR) <= 'Z')) {
+
+ int OP_LEN = 1;
+ (*NEXT_CHAR) ++;
+ while (((UPPER(**NEXT_CHAR) >= 'A') && (UPPER(**NEXT_CHAR) <= 'Z'))
+ && (!eoln(**NEXT_CHAR))) {
+ OP_LEN ++;
+ (*NEXT_CHAR) ++;
+ };
+ if (OP_LEN > LABEL_SIZE_1) {
+ /* -------------- (maybe) print error message, and truncate to 8 characters. */
+ if (PASS == pass1) {
+ char TEMP;
+ TEMP = START_OF_OPCODE[OP_LEN];
+ START_OF_OPCODE[OP_LEN] = '\0';
+ (void) fprintf(STREAM,
+ "eERROR[3]: OpCode field '%s' is too long. Truncating to %d charaters.\n"
+ ,START_OF_OPCODE,LABEL_SIZE_1);
+ START_OF_OPCODE[OP_LEN] = TEMP;
+ };
+ OP_LEN = LABEL_SIZE_1;
+ };
+ (void) strncpy(OPCODE,START_OF_OPCODE,OP_LEN);
+ OPCODE[OP_LEN] = '\0';
+ } else {
+ OPCODE[0] = 0;
+ }
+ }
+
+ /* ---------------------------- SCAN_LINE ---------------------------------- */
+ /* Reads in a sourse program line and does simple parsing. */
+ void SCAN_LINE (LOCATION_COUNTER,INPUT_LINE,LABEL,EXTENDED,OPERATOR,
+ REST,PASS,STREAM,INPUT_STREAM)
+ int LOCATION_COUNTER; /* SIC/XE location counter at start of line*/
+ char **INPUT_LINE; /* Where to return the source line */
+ char *LABEL; /* Where to return the label if one exists */
+ int *EXTENDED; /* Boolean: Is there a '+' before the */
+ /* operator. i.e. is this extended format*/
+ char *OPERATOR; /* Where to return the operator. */
+ char **REST; /* Where to return everything after the */
+ /* operator. Ignoring leading white-space*/
+ enum pass_type PASS; /* pass1 = do print error messages and */
+ /* source; pass2 = do not print error */
+ /* messages. */
+ FILE *STREAM; /* Stream for outputing error messages and */
+ /* the source code */
+ FILE *INPUT_STREAM; /* Where to get the source line from */
+ {
+ char *CH;
+
+ GET_LINE(INPUT_LINE,INPUT_STREAM);
+ (*REST) = (*INPUT_LINE);
+ if (PASS == pass1)
+ (void) fprintf(STREAM,"p%d %s\n",LOCATION_COUNTER,*REST);
+ CH = *REST;
+ if (*CH != '.') {
+ /* ---------------------- Not a comment line */
+ GET_LABEL(LABEL,*REST,&CH,PASS);
+ OUTPUT_BUFFER(&ERROR_REC_BUF,STREAM,1);
+ /* ---------------------- Must be white space after a operator. */
+ if (!IS_BLANK_OR_TAB(*CH) && !eoln(*CH)) {
+ if (PASS == pass1)
+ (void) fprintf(STREAM,
+ "eERROR[2]: Illegal LABEL/OPCODE seperater('%c') expected <tab> or <blank>.\n",
+ *CH);
+ CH ++;
+ };
+ /* ---------------------- remove white space characters */
+ while (IS_BLANK_OR_TAB(*CH) && !eoln(*CH)) CH ++;
+
+ if (*CH == '+') {
+ CH ++;
+ (*EXTENDED) = 1;
+ } else (*EXTENDED) = 0;
+
+ GET_OPCODE_STR(OPERATOR,&CH,PASS,STREAM);
+
+ if ((*EXTENDED == 1) && !strcmp(OPERATOR,"") && (PASS == pass1))
+ (void) fprintf(STREAM,"eERROR[5]: Expected an OPCODE after the '+'.\n");
+
+ /* ---------------------- Must be white space after a label. */
+ if (!IS_BLANK_OR_TAB(*CH) && !eoln(*CH)) {
+ if (PASS == pass1)
+ (void) fprintf(STREAM,
+ "eERROR[4]: Illegal OPCODE/OPERANDS seperater('%c') expected TAB or BLANK.\n",
+ *CH);
+ CH ++;
+ };
+ /* ---------------------- remove white space characters */
+ while (IS_BLANK_OR_TAB(*CH) && !eoln(*CH)) CH ++;
+
+ (*REST) = CH;
+ } else {
+ /* ---------------------- comment line */
+ LABEL[0] = '\0';
+ (*EXTENDED) = 0;
+ OPERATOR[0] = '\0';
+ }
+ }
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/scan_line.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,53 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =============================== scan_line.h ============================= */
+ /* Contains routines for doing simple parsing of source program (eg. return */
+ /* label, operator and everthing after the operator). */
+
+ /* pass_type Which pass the assembler is currently in. Used to */
+ /* surpress redisplaying pass1 error messages in */
+ /* pass2. */
+ enum pass_type {pass1,pass2};
+
+ /* ------------------------------ IS_BLANK_OR_TAB -------------------------- */
+ /* 1 parameter: */
+ /* 1) char CH; Character in question. */
+ /* True if CH is a blank or a tab, otherwise false. */
+ extern int IS_BLANK_OR_TAB();
+
+ /* ----------------------------- eoln -------------------------------------- */
+ /* 1 parameter: */
+ /* 1) char CH; Character in question. */
+ /* true if CH is the End Of LiNe character, otherwise false. */
+ extern int eoln();
+
+ /* -------------------------------- GET_LABEL ------------------------------ */
+ /* 4 parameters: */
+ /* 1) char *LABEL; Where to put the label if found. */
+ /* 2) char *INPUT; String to get the label from. */
+ /* 3) enum pass_type PASS; pass1 = buffers error messages in ERROR_REC_BUF*/
+ /* pass2 = don't buffer error messages. */
+ /* 4) char **NEXT_CHAR; where to start looking for the label in INPUT */
+ /* Get a SIC/XE Label (Letter followeb by zero to seven letters or digits). */
+ /* Return it in LABEL. Get it from INPUT starting from NEXT_CHAR. */
+ extern void GET_LABEL();
+
+ /* ---------------------------- SCAN_LINE ---------------------------------- */
+ /* 9 parameters: */
+ /* 1) int LOCATION_COUNTER; SIC/XE location counter at start of line*/
+ /* 2) char **INPUT_LINE; Where to return the source line */
+ /* 3) char *LABEL; Where to return the label if one exists */
+ /* 4) int *EXTENDED; Boolean: Is there a '+' before the */
+ /* operator. i.e. is this extended format*/
+ /* 5) char *OPERATOR; Where to return the operator. */
+ /* 6) char **REST; Where to return everything after the */
+ /* operator. Ignoring leading white-space*/
+ /* 7) enum pass_type PASS; pass1 = do print error messages and */
+ /* source; pass2 = do not print error */
+ /* messages. */
+ /* 8) FILE *STREAM; Stream for outputing error messages and */
+ /* the source code */
+ /* 9) FILE *INPUT_STREAM; Where to get the source line from */
+ /* Reads in a sourse program line and does simple parsing. */
+ extern void SCAN_LINE();
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,57 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ================================ stringI.c ============================== */
+ /* Reads in one line of input gauranteeing that it will return a pointer to */
+ /* the whole line, no matter how long it is (it uses CALLOC a version of */
+ /* MALLOC). */
+ #include <stdio.h>
+
+ /* CARRAGIAGE_RETURN <cr> is ascii 10 */
+ #define CARRIAGE_RETURN 10
+
+ /* LEX_LEN_INCREMENT For long strings, number of characters to */
+ /* increase the string buffer by on overflow. */
+ #define LEX_LEN_INCR 128
+
+ char CH = ' '; /* Current input Character */
+ char LEXEME[LEX_LEN_INCR+1]; /* Input String */
+
+ char *FRONT,*BACK; /* FRONT and BACK characters of Input String */
+ unsigned LEX_LEN = LEX_LEN_INCR;/* Size of the Input String Buffer */
+
+
+ /* ------------------------------- GETCHR ---------------------------------- */
+ /* gets the next character form input file and expands buffer if needed */
+ void GETCHR(FILE *STREAM)
+ {
+ /* int TEMP; */
+
+ /* --------- get next character */
+ CH = getc(STREAM);
+
+ /* TEMP = (int) (FRONT-BACK); */
+ if ((FRONT-BACK) < ((int)LEX_LEN-3)) {
+ /* --------- update input string appropriately */
+ FRONT ++;
+ *FRONT = CH;
+ *(FRONT+1) = '\0';
+ }
+ }
+
+ /* --------------------------------- GET_LINE ------------------------------ */
+ /* Read in a line from the input stream. */
+ void GET_LINE(char **LINE,FILE *STREAM)
+ {
+ /* -------- Clear input string */
+ LEXEME[0] = '\0';
+ /* -------- reset pointers */
+ BACK = LEXEME;
+ FRONT = BACK - 1;
+
+ GETCHR(STREAM);
+ while ((CH != CARRIAGE_RETURN) && !feof(STREAM))
+ GETCHR(STREAM);
+ *FRONT = '\0';
+ *LINE = LEXEME;
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/stringI.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,15 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* =============================== stringI.h =============================== */
+ /* Reads in one line of input gauranteeing that it will return a pointer to */
+ /* the whole line, no matter how long it is (it uses CALLOC a version of */
+ /* MALLOC). */
+
+ /* --------------------------------- GET_LINE ------------------------------ */
+ /* 2 parameters: */
+ /* 1) char **LINE; Points to the input line (string) when done*/
+ /* 2) FILE *STREAM; Where to get the line from. */
+ /* Read in a line from the input stream. */
+ extern void GET_LINE();
+
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.c:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.c Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,59 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ================================ sym_tab.c ============================== */
+ /* intialize, retrieve from, and store to the symbol table. Currently */
+ /* implemented with a linked list and linear search. */
+ #include "sym_tab.h"
+ #include <string.h>
+ #include <stdio.h>
+ #include <malloc.h>
+
+ /* -------------------------------- INIT_SYM_TAB --------------------------- */
+ /* Initialize the symbol table TABLE. */
+ void INIT_SYM_TAB(SYMBOL_TABLE *TABLE)
+ {
+ *TABLE = NULL;
+ }
+
+ /* ------------------------- LOOK_UP_SYMBOL -------------------------------- */
+ /* find a symbol in the table. Return a pointer to its entry in the table, if*/
+ /* found, otherwise return NULL. */
+ struct SYMBOL_TABLE_ENTRY *LOOK_UP_SYMBOL(char MODULE[],char LABEL[],
+ SYMBOL_TABLE *TABLE)
+ {
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+ TABLE_ENTRY = *TABLE;
+ while (TABLE_ENTRY != NULL)
+ {
+ if ( !strcmp((*TABLE_ENTRY).MODULE,MODULE) &&
+ !strcmp((*TABLE_ENTRY).LABEL,LABEL)) return TABLE_ENTRY;
+ TABLE_ENTRY = (*TABLE_ENTRY).NEXT;
+ }
+ return NULL;
+ }
+
+ /* -------------------------- INSERT_IN_SYM_TAB ---------------------------- */
+ /* If <MODULE,LABEL> pair is not in the symbol table, put it there and */
+ /* TRUE (integer 1). Otherwise return FALSE (integer 0). */
+ /* Puts onto front of the linked list. */
+ int INSERT_IN_SYM_TAB(char *MODULE,char *LABEL,int LOCATION,enum kind TYPE,
+ SYMBOL_TABLE *TABLE)
+ {
+ struct SYMBOL_TABLE_ENTRY *TABLE_ENTRY;
+
+ TABLE_ENTRY = LOOK_UP_SYMBOL(MODULE,LABEL,TABLE);
+ if (TABLE_ENTRY == NULL)
+ {
+ TABLE_ENTRY = (struct SYMBOL_TABLE_ENTRY *) malloc(sizeof(struct SYMBOL_TABLE_ENTRY));
+ (*TABLE_ENTRY).NEXT = *TABLE;
+ (void) strcpy((*TABLE_ENTRY).MODULE, MODULE);
+ (void) strcpy((*TABLE_ENTRY).LABEL, LABEL);
+ (*TABLE_ENTRY).LOCATION = LOCATION;
+ (*TABLE_ENTRY).LENGTH = 0;
+ (*TABLE_ENTRY).TYPE = TYPE;
+ *TABLE = TABLE_ENTRY;
+ return 1;
+ }
+ else return 0;
+ }
Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.h:1.1
*** /dev/null Tue Oct 5 13:24:30 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/assembler/sym_tab.h Tue Oct 5 13:24:16 2004
***************
*** 0 ****
--- 1,54 ----
+ /* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
+ /* Permission to use this code is granted as long as the copyright */
+ /* notice remains in place. */
+ /* ========================= sym_tab.h ===================================== */
+ #include "constants.h"
+
+ /* kind What kind/type of symbol is it. */
+ enum kind {RELATIVE,ABSOLUTE,EXTERN_REF,MODULE,GLOBAL,UNDEFINED};
+
+ /* SYMBOL_TABLE_ENTRY type of a symbol table entry. Part of a linked list*/
+ typedef struct SYMBOL_TABLE_ENTRY {
+ char LABEL[LABEL_SIZE_1+1]; /* Name of the symbol. */
+ char MODULE[LABEL_SIZE_1+1]; /* [Program] Module the symbol was found */
+ /* int. */
+ int LOCATION; /* Location in SICs memory this label */
+ /* represents. For module names it */
+ /* is the starting address. For */
+ /* constants it is the value. */
+ int LENGTH; /* Only for module names, the length of */
+ /* the module. */
+ enum kind TYPE; /* kind/type of label (relative, ...) */
+ struct SYMBOL_TABLE_ENTRY *NEXT; /* Pointer to next entry in the list */
+ } *SYMBOL_TABLE;
+
+ /* -------------------------------- INIT_SYM_TAB --------------------------- */
+ /* 1 parameter: */
+ /* 1) SYMBOL_TABLE *TABLE; */
+ /* Initialize the symbol table TABLE. */
+ extern void INIT_SYM_TAB();
+
+ /* ------------------------- LOOK_UP_SYMBOL -------------------------------- */
+ /* 3 parameters: */
+ /* 1) char MODULE[]; /* Name of module label found it. */
+ /* 2) char LABEL[]; /* Label to look for. */
+ /* 3) SYMBOL_TABLE *TABLE; /* Table to look in. */
+ /* find a symbol in the table. Return a pointer to its entry in the table, if*/
+ /* found, otherwise return NULL. */
+ extern struct SYMBOL_TABLE_ENTRY *LOOK_UP_SYMBOL();
+
+ /* -------------------------- INSERT_IN_SYM_TAB ---------------------------- */
+ /* 5 parameters: */
+ /* 1) char *LABEL; Label to add. */
+ /* 2) char *MODULE; Module that this label was found in. */
+ /* 3) int LOCATION; What the entries LOCATION field */
+ /* should be set to. */
+ /* 4) enum kind TYPE; What the entries TYPE field should be */
+ /* set to. */
+ /* 5) SYMBOL_TABLE *TABLE; Table to add <MODULE,LABEL> to. */
+ /* If <MODULE,LABEL> pair is not in the symbol table, put it there and */
+ /* TRUE (integer 1). Otherwise return FALSE (integer 0). */
+ /* Puts onto front of the linked list. */
+ extern int INSERT_IN_SYM_TAB();
+
+
More information about the llvm-commits
mailing list