12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106 |
- ## This file was generated by running:
- ## cat functions/exit.c functions/file.c functions/file_print.c functions/malloc.c functions/calloc.c functions/match.c functions/numerate_number.c functions/string.c test/test23/M1-macro.c >| ../stage0/stage3/M1-macro_x86.c
- ## inside the M2-Planet repo
- ## Copyright (C) 2016 Jeremiah Orians
- ## This file is part of stage0.
- ##
- ## stage0 is free software: you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation, either version 3 of the License, or
- ## (at your option) any later version.
- ##
- ## stage0 is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
- // CONSTANT EXIT_FAILURE 1
- // CONSTANT EXIT_SUCCESS 0
- void exit(int value)
- {
- asm("POP_ebx"
- "POP_ebx"
- "LOAD_IMMEDIATE_eax %1"
- "INT_80");
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- // CONSTANT stdin 0
- // CONSTANT stdout 1
- // CONSTANT stderr 2
- // CONSTANT EOF 0xFFFFFFFF
- int fgetc(FILE* f)
- {
- asm("LOAD_IMMEDIATE_eax %3"
- "LOAD_EFFECTIVE_ADDRESS_ebx %4"
- "LOAD_INTEGER_ebx"
- "PUSH_ebx"
- "COPY_esp_to_ecx"
- "LOAD_IMMEDIATE_edx %1"
- "INT_80"
- "TEST"
- "POP_eax"
- "JUMP_NE8 !FUNCTION_fgetc_Done"
- "LOAD_IMMEDIATE_eax %-1"
- ":FUNCTION_fgetc_Done");
- }
- void fputc(char s, FILE* f)
- {
- asm("LOAD_IMMEDIATE_eax %4"
- "LOAD_EFFECTIVE_ADDRESS_ebx %4"
- "LOAD_INTEGER_ebx"
- "LOAD_EFFECTIVE_ADDRESS_ecx %8"
- "LOAD_IMMEDIATE_edx %1"
- "INT_80");
- }
- /* Important values needed for open
- * O_RDONLY => 0
- * O_WRONLY => 1
- * O_RDWR => 2
- * O_CREAT => 64
- * O_TRUNC => 512
- * S_IRWXU => 00700
- * S_IXUSR => 00100
- * S_IWUSR => 00200
- * S_IRUSR => 00400
- */
- FILE* open(char* name, int flag, int mode)
- {
- asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
- "LOAD_INTEGER_ebx"
- "LOAD_EFFECTIVE_ADDRESS_ecx %8"
- "LOAD_INTEGER_ecx"
- "LOAD_EFFECTIVE_ADDRESS_edx %4"
- "LOAD_INTEGER_edx"
- "LOAD_IMMEDIATE_eax %5"
- "INT_80");
- }
- FILE* fopen(char* filename, char* mode)
- {
- FILE* f;
- if('w' == mode[0])
- { /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
- f = open(filename, 577 , 384);
- }
- else
- { /* Everything else is a read */
- f = open(filename, 0, 0);
- }
- /* Negative numbers are error codes */
- if(0 > f)
- {
- return 0;
- }
- return f;
- }
- int close(int fd)
- {
- asm("LOAD_EFFECTIVE_ADDRESS_ebx %4"
- "LOAD_IMMEDIATE_eax %6"
- "INT_80");
- }
- int fclose(FILE* stream)
- {
- int error = close(stream);
- return error;
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- #include<stdio.h>
- // void fputc(char s, FILE* f);
- void file_print(char* s, FILE* f)
- {
- while(0 != s[0])
- {
- fputc(s[0], f);
- s = s + 1;
- }
- }
- ## Copyright (C) 2016 Jeremiah Orians
- ## This file is part of stage0.
- ##
- ## stage0 is free software: you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation, either version 3 of the License, or
- ## (at your option) any later version.
- ##
- ## stage0 is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
- // CONSTANT NULL 0
- void* malloc(int size)
- {
- asm("STORE_eax_into_ESP_IMMEDIATE8 !4"
- "PUSH_eax"
- "LOAD_IMMEDIATE_eax %45"
- "LOAD_IMMEDIATE_ebx %0"
- "INT_80"
- "POP_ebx"
- "ADD_eax_to_ebx"
- "PUSH_eax"
- "PUSH_ebx"
- "LOAD_IMMEDIATE_eax %45"
- "INT_80"
- "POP_ebx"
- "CMP"
- "POP_eax"
- "JUMP_EQ8 !FUNCTION_malloc_Done"
- "LOAD_IMMEDIATE_eax %-1"
- ":FUNCTION_malloc_Done");
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- // void* malloc(int size);
- void* memset(void* ptr, int value, int num)
- {
- char* s;
- for(s = ptr; 0 < num; num = num - 1)
- {
- s[0] = value;
- s = s + 1;
- }
- }
- void* calloc(int count, int size)
- {
- void* ret = malloc(count * size);
- memset(ret, 0, (count * size));
- return ret;
- }
- void free(void* l)
- {
- return;
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- #define FALSE 0
- // CONSTANT FALSE 0
- #define TRUE 1
- // CONSTANT TRUE 1
- int match(char* a, char* b)
- {
- int i = -1;
- do
- {
- i = i + 1;
- if(a[i] != b[i])
- {
- return FALSE;
- }
- } while((0 != a[i]) && (0 !=b[i]));
- return TRUE;
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- #include<stdlib.h>
- #include<string.h>
- // void* calloc(int count, int size);
- #define TRUE 1
- //CONSTANT TRUE 1
- #define FALSE 0
- //CONSTANT FALSE 0
- char* numerate_number(int a)
- {
- char* result = calloc(16, sizeof(char));
- int i = 0;
- /* Deal with Zero case */
- if(0 == a)
- {
- result[0] = '0';
- return result;
- }
- /* Deal with negatives */
- if(0 > a)
- {
- result[0] = '-';
- i = 1;
- a = a * -1;
- }
- /* Using the largest 10^n number possible in 32bits */
- int divisor = 0x3B9ACA00;
- /* Skip leading Zeros */
- while(0 == (a / divisor)) divisor = divisor / 10;
- /* Now simply collect numbers until divisor is gone */
- while(0 < divisor)
- {
- result[i] = ((a / divisor) + 48);
- a = a % divisor;
- divisor = divisor / 10;
- i = i + 1;
- }
- return result;
- }
- int char2hex(int c)
- {
- if (c >= '0' && c <= '9') return (c - 48);
- else if (c >= 'a' && c <= 'f') return (c - 87);
- else if (c >= 'A' && c <= 'F') return (c - 55);
- else return -1;
- }
- int hex2char(int c)
- {
- if((c >= 0) && (c <= 9)) return (c + 48);
- else if((c >= 10) && (c <= 15)) return (c + 55);
- else return -1;
- }
- int char2dec(int c)
- {
- if (c >= '0' && c <= '9') return (c - 48);
- else return -1;
- }
- int dec2char(int c)
- {
- if((c >= 0) && (c <= 9)) return (c + 48);
- else return -1;
- }
- int numerate_string(char *a)
- {
- int count = 0;
- int index;
- int negative;
- /* If NULL string */
- if(0 == a[0])
- {
- return 0;
- }
- /* Deal with hex */
- else if (a[0] == '0' && a[1] == 'x')
- {
- if('-' == a[2])
- {
- negative = TRUE;
- index = 3;
- }
- else
- {
- negative = FALSE;
- index = 2;
- }
- while(0 != a[index])
- {
- if(-1 == char2hex(a[index])) return 0;
- count = (16 * count) + char2hex(a[index]);
- index = index + 1;
- }
- }
- /* Deal with decimal */
- else
- {
- if('-' == a[0])
- {
- negative = TRUE;
- index = 1;
- }
- else
- {
- negative = FALSE;
- index = 0;
- }
- while(0 != a[index])
- {
- if(-1 == char2dec(a[index])) return 0;
- count = (10 * count) + char2dec(a[index]);
- index = index + 1;
- }
- }
- if(negative)
- {
- count = count * -1;
- }
- return count;
- }
- /* Copyright (C) 2016 Jeremiah Orians
- * This file is part of stage0.
- *
- * stage0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * stage0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with stage0. If not, see <http://www.gnu.org/licenses/>.
- */
- #include<stdlib.h>
- #define MAX_STRING 4096
- //CONSTANT MAX_STRING 4096
- // void* calloc(int count, int size);
- char* copy_string(char* target, char* source)
- {
- while(0 != source[0])
- {
- target[0] = source[0];
- target = target + 1;
- source = source + 1;
- }
- return target;
- }
- char* postpend_char(char* s, char a)
- {
- char* ret = calloc(MAX_STRING, sizeof(char));
- char* hold = copy_string(ret, s);
- hold[0] = a;
- return ret;
- }
- char* prepend_char(char a, char* s)
- {
- char* ret = calloc(MAX_STRING, sizeof(char));
- ret[0] = a;
- copy_string((ret+1), s);
- return ret;
- }
- char* prepend_string(char* add, char* base)
- {
- char* ret = calloc(MAX_STRING, sizeof(char));
- copy_string(copy_string(ret, add), base);
- return ret;
- }
- int string_length(char* a)
- {
- int i = 0;
- while(0 != a[i]) i = i + 1;
- return i;
- }
- /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
- /* Copyright (C) 2016 Jeremiah Orians
- * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
- * This file is part of mescc-tools.
- *
- * mescc-tools is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * mescc-tools is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <getopt.h>
- #define max_string 4096
- //CONSTANT max_string 4096
- #define MACRO 1
- //CONSTANT MACRO 1
- #define STR 2
- //CONSTANT STR 2
- #define TRUE 1
- //CONSTANT TRUE 1
- #define FALSE 0
- //CONSTANT FALSE 0
- void file_print(char* s, FILE* f);
- int match(char* a, char* b);
- int string_length(char* a);
- char* numerate_number(int a);
- int numerate_string(char *a);
- int hex2char(int c);
- FILE* source_file;
- FILE* destination_file;
- int BigEndian;
- int BigBitEndian;
- int ByteMode;
- int Architecture;
- struct Token
- {
- struct Token* next;
- int type;
- char* Text;
- char* Expression;
- };
- struct Token* newToken()
- {
- struct Token* p;
- p = calloc (1, sizeof (struct Token));
- if (NULL == p)
- {
- file_print("calloc failed.\n", stderr);
- exit (EXIT_FAILURE);
- }
- return p;
- }
- struct Token* reverse_list(struct Token* head)
- {
- struct Token* root = NULL;
- while(NULL != head)
- {
- struct Token* next = head->next;
- head->next = root;
- root = head;
- head = next;
- }
- return root;
- }
- void purge_lineComment()
- {
- int c = fgetc(source_file);
- while((10 != c) && (13 != c))
- {
- c = fgetc(source_file);
- }
- }
- char* store_atom(char c)
- {
- char* store = calloc(max_string + 1, sizeof(char));
- if(NULL == store)
- {
- file_print("Exhusted available memory\n", stderr);
- exit(EXIT_FAILURE);
- }
- int ch = c;
- int i = 0;
- do
- {
- store[i] = ch;
- ch = fgetc(source_file);
- i = i + 1;
- } while ((9 != ch) && (10 != ch) && (32 != ch) && (i <= max_string));
- return store;
- }
- char* store_string(char c)
- {
- char* store = calloc(max_string + 1, sizeof(char));
- if(NULL == store)
- {
- file_print("Exhusted available memory\n", stderr);
- exit(EXIT_FAILURE);
- }
- int ch = c;
- int i = 0;
- do
- {
- store[i] = ch;
- i = i + 1;
- ch = fgetc(source_file);
- if(-1 == ch)
- {
- file_print("Unmatched \"!\n", stderr);
- exit(EXIT_FAILURE);
- }
- if(max_string == i)
- {
- file_print("String: ", stderr);
- file_print(store, stderr);
- file_print(" exceeds max string size\n", stderr);
- exit(EXIT_FAILURE);
- }
- } while(ch != c);
- return store;
- }
- struct Token* Tokenize_Line(struct Token* head)
- {
- int c;
- struct Token* p;
- do
- {
- restart:
- c = fgetc(source_file);
- if((35 == c) || (59 == c))
- {
- purge_lineComment();
- goto restart;
- }
- if((9 == c) || (10 == c) || (32 == c))
- {
- goto restart;
- }
- if(-1 == c)
- {
- goto done;
- }
- p = newToken();
- if((34 == c) || (39 == c))
- {
- p->Text = store_string(c);
- p->type = STR;
- }
- else
- {
- p->Text = store_atom(c);
- }
- p->next = head;
- head = p;
- } while(TRUE);
- done:
- return head;
- }
- void setExpression(struct Token* p, char *c, char *Exp)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- /* Leave macros alone */
- if((i->type & MACRO))
- {
- continue;
- }
- else if(match(i->Text, c))
- { /* Only if there is an exact match replace */
- i->Expression = Exp;
- }
- }
- }
- void identify_macros(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if(match(i->Text, "DEFINE"))
- {
- i->type = MACRO;
- i->Text = i->next->Text;
- if(i->next->next->type & STR)
- {
- i->Expression = i->next->next->Text + 1;
- }
- else
- {
- i->Expression = i->next->next->Text;
- }
- i->next = i->next->next->next;
- }
- }
- }
- void line_macro(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if(i->type & MACRO)
- {
- setExpression(i->next, i->Text, i->Expression);
- }
- }
- }
- void hexify_string(struct Token* p)
- {
- char* table = "0123456789ABCDEF";
- int i = ((string_length(p->Text + 1)/4) + 1) * 8;
- char* d = calloc(max_string, sizeof(char));
- p->Expression = d;
- while(0 < i)
- {
- i = i - 1;
- d[i] = 0x30;
- }
- while( i < max_string)
- {
- if(0 == p->Text[i+1])
- {
- i = max_string;
- }
- else
- {
- d[2*i] = table[p->Text[i+1] / 16];
- d[2*i + 1] = table[p->Text[i+1] % 16];
- i = i + 1;
- }
- }
- }
- void process_string(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if(i->type & STR)
- {
- if('\'' == i->Text[0])
- {
- i->Expression = i->Text + 1;
- }
- else if('"' == i->Text[0])
- {
- hexify_string(i);
- }
- }
- }
- }
- void preserve_other(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if((NULL == i->Expression) && !(i->type & MACRO))
- {
- char c = i->Text[0];
- if(('!' == c) ||('@' == c) ||('$' == c) ||('%' == c) ||('&' == c) ||(':' == c))
- {
- i->Expression = i->Text;
- }
- else
- {
- file_print("Received invalid other; ", stderr);
- file_print(i->Text, stderr);
- file_print("\n", stderr);
- exit(EXIT_FAILURE);
- }
- }
- }
- }
- void bound_values(int displacement, int number_of_bytes, int low, int high)
- {
- if((high < displacement) || (displacement < low))
- {
- file_print("A displacement of ", stderr);
- file_print(numerate_number(displacement), stderr);
- file_print(" does not fit in ", stderr);
- file_print(numerate_number(number_of_bytes), stderr);
- file_print(" bytes\n", stderr);
- exit(EXIT_FAILURE);
- }
- }
- void range_check(int displacement, int number_of_bytes)
- {
- if(4 == number_of_bytes) return;
- else if(3 == number_of_bytes)
- {
- bound_values(displacement, number_of_bytes, -8388608, 16777216);
- return;
- }
- else if(2 == number_of_bytes)
- {
- bound_values(displacement, number_of_bytes, -32768, 65535);
- return;
- }
- else if(1 == number_of_bytes)
- {
- bound_values(displacement, number_of_bytes, -128, 255);
- return;
- }
- file_print("Received an invalid number of bytes in range_check\n", stderr);
- exit(EXIT_FAILURE);
- }
- void reverseBitOrder(char* c)
- {
- if(NULL == c) return;
- if(0 == c[1]) return;
- int hold = c[0];
- if(16 == ByteMode)
- {
- c[0] = c[1];
- c[1] = hold;
- reverseBitOrder(c+2);
- }
- else if(8 == ByteMode)
- {
- c[0] = c[2];
- c[2] = hold;
- reverseBitOrder(c+3);
- }
- else if(2 == ByteMode)
- {
- c[0] = c[7];
- c[7] = hold;
- hold = c[1];
- c[1] = c[6];
- c[6] = hold;
- hold = c[2];
- c[2] = c[5];
- c[5] = hold;
- hold = c[3];
- c[3] = c[4];
- c[4] = hold;
- reverseBitOrder(c+8);
- }
- }
- void LittleEndian(char* start)
- {
- char* end = start;
- char* c = start;
- while(0 != end[0]) end = end + 1;
- int hold;
- for(end = end - 1; start < end; start = start + 1)
- {
- hold = start[0];
- start[0] = end[0];
- end[0] = hold;
- end = end - 1;
- }
- if(BigBitEndian) reverseBitOrder(c);
- }
- int stringify(char* s, int digits, int divisor, int value, int shift)
- {
- int i = value;
- if(digits > 1)
- {
- i = stringify(s+1, (digits - 1), divisor, value, shift);
- }
- s[0] = hex2char(i & (divisor - 1));
- return (i >> shift);
- }
- char* express_number(int value, char c)
- {
- char* ch = calloc(42, sizeof(char));
- int size;
- int number_of_bytes;
- int shift;
- if('!' == c)
- {
- number_of_bytes = 1;
- value = value & 0xFF;
- }
- else if('@' == c)
- {
- number_of_bytes = 2;
- value = value & 0xFFFF;
- }
- else if('%' == c)
- {
- number_of_bytes = 4;
- value = value & 0xFFFFFFFF;
- }
- else
- {
- file_print("Given symbol ", stderr);
- fputc(c, stderr);
- file_print(" to express immediate value ", stderr);
- file_print(numerate_number(value), stderr);
- fputc('\n', stderr);
- exit(EXIT_FAILURE);
- }
- range_check(value, number_of_bytes);
- if(16 == ByteMode)
- {
- size = number_of_bytes * 2;
- shift = 4;
- }
- else if(8 == ByteMode)
- {
- size = number_of_bytes * 3;
- shift = 3;
- }
- else if(2 == ByteMode)
- {
- size = number_of_bytes * 8;
- shift = 1;
- }
- else
- {
- file_print("Got invalid ByteMode in express_number\n", stderr);
- exit(EXIT_FAILURE);
- }
- stringify(ch, size, ByteMode, value, shift);
- if(!BigEndian) LittleEndian(ch);
- else if(!BigBitEndian) reverseBitOrder(ch);
- return ch;
- }
- void eval_immediates(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if((NULL == i->Expression) && !(i->type & MACRO))
- {
- int value;
- if((1 == Architecture) || (2 == Architecture) || (40 == Architecture))
- {
- value = numerate_string(i->Text + 1);
- if(('0' == i->Text[1]) || (0 != value))
- {
- i->Expression = express_number(value, i->Text[0]);
- }
- }
- else if(0 == Architecture)
- {
- value = numerate_string(i->Text);
- if(('0' == i->Text[0]) || (0 != value))
- {
- i->Expression = express_number(value, '@');
- }
- }
- else
- {
- file_print("Unknown architecture received in eval_immediates\n", stderr);
- exit(EXIT_FAILURE);
- }
- }
- }
- }
- void print_hex(struct Token* p)
- {
- struct Token* i;
- for(i = p; NULL != i; i = i->next)
- {
- if(i->type ^ MACRO)
- {
- fputc('\n', destination_file);
- file_print(i->Expression, destination_file);
- }
- }
- fputc('\n', destination_file);
- }
- /* Standard C main program */
- int main(int argc, char **argv)
- {
- BigEndian = TRUE;
- struct Token* head = NULL;
- Architecture = 0;
- destination_file = stdout;
- BigBitEndian = TRUE;
- ByteMode = 16;
- int option_index = 1;
- while(option_index <= argc)
- {
- if(NULL == argv[option_index])
- {
- option_index = option_index + 1;
- }
- else if(match(argv[option_index], "--BigEndian"))
- {
- BigEndian = TRUE;
- option_index = option_index + 1;
- }
- else if(match(argv[option_index], "--LittleEndian"))
- {
- BigEndian = FALSE;
- option_index = option_index + 1;
- }
- else if(match(argv[option_index], "-A") || match(argv[option_index], "--Architecture"))
- {
- Architecture = numerate_string(argv[option_index + 1]);
- option_index = option_index + 2;
- }
- else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
- {
- ByteMode = 2;
- option_index = option_index + 1;
- }
- else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
- {
- file_print("Usage: ", stderr);
- file_print(argv[0], stderr);
- file_print(" -f FILENAME1 {-f FILENAME2} (--BigEndian|--LittleEndian) ", stderr);
- file_print("[--Architecture 12345]\nArchitecture 0: Knight; 1: x86; 2: AMD64; 40: armv7", stderr);
- exit(EXIT_SUCCESS);
- }
- else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
- {
- source_file = fopen(argv[option_index + 1], "r");
- if(NULL == source_file)
- {
- file_print("The file: ", stderr);
- file_print(argv[option_index + 1], stderr);
- file_print(" can not be opened!\n", stderr);
- exit(EXIT_FAILURE);
- }
- head = Tokenize_Line(head);
- option_index = option_index + 2;
- }
- else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
- {
- destination_file = fopen(argv[option_index + 1], "w");
- if(NULL == destination_file)
- {
- file_print("The file: ", stderr);
- file_print(argv[option_index + 1], stderr);
- file_print(" can not be opened!\n", stderr);
- exit(EXIT_FAILURE);
- }
- option_index = option_index + 2;
- }
- else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
- {
- ByteMode = 8;
- option_index = option_index + 1;
- }
- else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
- {
- file_print("M1 0.3\n", stdout);
- exit(EXIT_SUCCESS);
- }
- else
- {
- file_print("Unknown option\n", stderr);
- exit(EXIT_FAILURE);
- }
- }
- if(NULL == head)
- {
- file_print("Either no input files were given or they were empty\n", stderr);
- exit(EXIT_FAILURE);
- }
- head = reverse_list(head);
- identify_macros(head);
- line_macro(head);
- process_string(head);
- eval_immediates(head);
- preserve_other(head);
- print_hex(head);
- return EXIT_SUCCESS;
- }
|