URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
Compare Revisions
- This comparison shows the changes necessary to convert path
/thor
- from Rev 53 to Rev 54
- ↔ Reverse comparison
Rev 53 → Rev 54
/trunk/FT64v5/software/AS64/source/FT64.cpp
58,6 → 58,14
#define LB16 -31653LL |
|
// ---------------------------------------------------------------------------- |
// ---------------------------------------------------------------------------- |
|
static void error(char *msg) |
{ |
printf("%s. (%d)\n", msg, /*mname.c_str(), */lineno); |
} |
|
// ---------------------------------------------------------------------------- |
// Return the register number or -1 if not a register. |
// Parses pretty register names like SP or BP in addition to r1,r2,etc. |
// ---------------------------------------------------------------------------- |
1028,7 → 1036,7
inptr++; |
} |
else |
printf("Illegal float size.\r\n"); |
error("Illegal float size"); |
} |
switch(sz) { |
case 'h': sz = 0; break; |
1062,7 → 1070,7
htblmax++; |
return; |
} |
printf("Too many instructions.\r\n"); |
error("Too many instructions"); |
return; |
} |
if (pass > 3) { |
1286,11 → 1294,11
break; |
case 'd': case 'D': *sz = 0x83; break; |
case 'i': case 'I': *sz = 0x43; break; |
default: |
printf("%d bad size.\r\n", lineno); |
*sz = 3; |
} |
inptr += 1; |
default: |
error("Bad size"); |
*sz = 3; |
} |
inptr += 1; |
} |
|
// --------------------------------------------------------------------------- |
1330,21 → 1338,21
|
static void process_riop(int64_t opcode6) |
{ |
int Ra; |
int Rt, Rtp; |
char *p; |
int64_t val; |
int Ra; |
int Rt, Rtp; |
char *p; |
int64_t val; |
int sz = 3; |
|
p = inptr; |
p = inptr; |
if (*p == '.') |
getSz(&sz); |
Rt = getRegisterX(); |
need(','); |
Ra = getRegisterX(); |
need(','); |
NextToken(); |
val = expr(); |
need(','); |
Ra = getRegisterX(); |
need(','); |
NextToken(); |
val = expr(); |
if (opcode6==-4LL) { // subi |
val = -val; |
opcode6 = 0x04LL; // change to addi |
1360,7 → 1368,7
(2 << 6) | |
(((val >> 3) & 0x1) << 5) | |
regSP, 0, 2); |
return; |
goto xit; |
} |
} |
else { |
1371,7 → 1379,7
(2 << 6) | |
((val & 0x1) << 5) | |
Ra, 0, 2); |
return; |
goto xit; |
} |
} |
} |
1386,7 → 1394,7
(((val >> 3) & 0x1) << 5) | |
Rt, 0, 2 |
); |
return; |
goto xit; |
} |
} |
// Compress ORI ? |
1401,7 → 1409,7
Rtp, 0, 2 |
); |
} |
return; |
goto xit; |
} |
if (!IsNBit(val, 14)) { |
if (!IsNBit(val, 30)) { |
1420,7 → 1428,7
(23 << 13) | |
(Ra << 8) | |
0x02, !expand_flag, 4); |
return; |
goto xit; |
} |
emit_insn( |
(val << 18LL) | |
1428,10 → 1436,12
(Ra << 8) | |
(1 << 6) | |
opcode6, !expand_flag, 6); |
return; |
goto xit; |
} |
emit_insn( |
(val << 18)|(Rt << 13)|(Ra << 8)|opcode6,!expand_flag,4); |
xit: |
ScanToEOL(); |
} |
|
// --------------------------------------------------------------------------- |
1511,7 → 1521,7
); |
return; |
} |
printf("Illegal set immediate instruction %d.", lineno); |
error("Illegal set immediate instruction"); |
return; |
} |
if (!IsNBit(val, 14)) { |
1645,10 → 1655,10
NextToken(); |
if (token=='#') { |
if (iop < 0 && iop!=-4) |
printf("Immediate mode not supported (%d).", lineno); |
inptr = p; |
process_riop(iop); |
return; |
error("Immediate mode not supported"); |
inptr = p; |
process_riop(iop); |
return; |
} |
prevToken(); |
Rb = getRegisterX(); |
1662,7 → 1672,7
(Rt), |
0,2 |
); |
return; |
goto xit; |
} |
// Compress SUB |
if (funct6 == 0x05 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) { |
1676,7 → 1686,7
(Rtp), |
0, 2 |
); |
return; |
goto xit; |
} |
// Compress AND |
if (funct6 == 0x08 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) { |
1690,7 → 1700,7
(Rtp), |
0, 2 |
); |
return; |
goto xit; |
} |
// Compress OR |
if (funct6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) { |
1704,7 → 1714,7
(Rtp), |
0, 2 |
); |
return; |
goto xit; |
} |
// Compress XOR |
if (funct6 == 0x0A && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) { |
1718,19 → 1728,21
(Rtp), |
0, 2 |
); |
return; |
goto xit; |
} |
//prevToken(); |
if (funct6==0x2E || funct6==0x2C || funct6==0x2D) { |
funct6 += 0x10; // change to divmod |
emit_insn((funct6<<26LL)||(1<<23)||(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4); |
return; |
goto xit; |
} |
else if (funct6==0x3C || funct6==0x3D || funct6==0x3E) { |
emit_insn((funct6<<26LL)||(0<<23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4); |
return; |
goto xit; |
} |
emit_insn((funct6<<26LL)|(sz << 23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4); |
xit: |
ScanToEOL(); |
} |
|
// --------------------------------------------------------------------------- |
1812,31 → 1824,29
|
static void process_jal(int64_t oc) |
{ |
int64_t addr, val; |
int Ra; |
int Rt; |
int64_t addr, val; |
int Ra; |
int Rt; |
bool noRt; |
char *p; |
|
noRt = false; |
Ra = 0; |
Rt = 0; |
Rt = 0; |
p = inptr; |
NextToken(); |
NextToken(); |
if (token == '(' || token == '[') { |
j1: |
Ra = getRegisterX(); |
if (Ra == -1) { |
printf("Expecting a register\r\n"); |
return; |
goto xit; |
} |
// Simple jmp [Rn] |
else { |
if (token != ')' && token != ']') |
printf("Missing close bracket\r\n"); |
emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4); |
return; |
} |
if (token != ')' && token != ']') |
printf("Missing close bracket %d\n", lineno); |
emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4); |
goto xit; |
} |
else |
inptr = p; |
1849,10 → 1859,10
goto j1; |
} |
else { |
Rt = 0; |
noRt = true; |
} |
addr = expr(); |
Rt = 0; |
noRt = true; |
} |
addr = expr(); |
// d(Rn)? |
//NextToken(); |
if (token=='(' || token=='[') { |
1871,7 → 1881,7
(Rt << 13) | |
(Ra << 8) | |
0x18, !expand_flag, 4); |
return; |
goto xit; |
} |
if (IsNBit(val, 30)) { |
emit_insn( |
1880,7 → 1890,7
(Ra << 8) | |
(1 << 6) | |
0x18, !expand_flag, 6); |
return; |
goto xit; |
} |
|
{ |
1900,13 → 1910,15
(0 << 18) | |
(Rt << 12) | |
(23 << 8) | 0x18, !expand_flag, 4); |
return; |
goto xit; |
} |
emit_insn( |
(Rt << 12) | |
(23 << 8) | 0x18, !expand_flag, 4); |
return; |
goto xit; |
} |
xit: |
ScanToEOL(); |
} |
|
// --------------------------------------------------------------------------- |
2247,20 → 2259,20
|
static void process_bcc(int opcode6, int opcode4) |
{ |
int Ra, Rb, pred; |
int Ra, Rb, pred; |
int fmt; |
int64_t val; |
int64_t disp; |
int64_t val; |
int64_t disp, cdisp; |
char *p1; |
bool ins48 = false; |
|
fmt = GetFPSize(); |
fmt = GetFPSize(); |
pred = 0; |
p1 = inptr; |
Ra = getRegisterX(); |
need(','); |
Rb = getRegisterX(); |
need(','); |
Ra = getRegisterX(); |
need(','); |
Rb = getRegisterX(); |
need(','); |
NextToken(); |
if (token=='#' && opcode4==0) { |
inptr = p1; |
2269,31 → 2281,32
} |
val = expr(); |
disp = val - (code_address + 4); |
cdisp = val - (code_address + 2); |
if (!IsNBit(disp, 12)) { |
error("Branch displacement too large"); |
disp = val - (code_address + 6); |
ins48 = true; |
} |
disp >>= 1; |
cdisp >>= 1; |
// Check for compressed bnez |
if (opcode4 == 1 && Rb == 0 && IsNBit(disp+1,7)) { // disp+1 to account for 2 byte instruction |
disp++; |
if (opcode4 == 1 && Rb == 0 && IsNBit(cdisp,7)) { |
emit_insn( |
(3 << 14) | |
(((disp >> 1) & 0x3f) << 8) | |
(((cdisp >> 1) & 0x3f) << 8) | |
(2 << 6) | |
((disp & 1) << 5) | |
((cdisp & 1) << 5) | |
Ra,0,2 |
); |
return; |
} |
// compressed beqz |
if (opcode4 == 0 && Rb == 0 && IsNBit(disp+1, 7)) { |
disp++; |
if (opcode4 == 0 && Rb == 0 && IsNBit(cdisp, 7)) { |
emit_insn( |
(2 << 14) | |
(((disp >> 1) & 0x3f) << 8) | |
(((cdisp >> 1) & 0x3f) << 8) | |
(2 << 6) | |
((disp & 1) << 5) | |
((cdisp & 1) << 5) | |
Ra, 0, 2 |
); |
return; |
2348,7 → 2361,7
NextToken(); |
val = expr(); |
disp = val - (code_address + 4LL); |
disp >>= 1; |
disp >>= 1LL; |
emit_insn( |
(disp << 21LL) | |
((opcode3 & 3) << 19) | |
2358,7 → 2371,7
); |
return; |
} |
printf("dbnz: target must be a label %d.\n", lineno); |
error("dbnz: target must be a label"); |
emit_insn( |
(opcode3 << 19) | |
(0 << 13) | |
2413,7 → 2426,7
); |
return; |
} |
printf("ibne: target must be a label %d.\n", lineno); |
error("ibne: target must be a label"); |
emit_insn( |
(opcode3 << 19) | |
(Rb << 13) | |
2423,49 → 2436,77
} |
|
// --------------------------------------------------------------------------- |
// bfextu r1,r2,#1,#63 |
// bfextu r1,#1,#63,r2 |
// --------------------------------------------------------------------------- |
|
static void process_bitfield(int64_t oc) |
{ |
int Ra; |
int Rt; |
int64_t mb; |
int64_t me; |
int Ra, Rb, Rc; |
int Rt; |
int64_t mb; |
int64_t me; |
int64_t val; |
int64_t op; |
int sz = 3; |
char *p; |
bool gmb, gme, gval; |
|
gmb = gme = gval = false; |
p = inptr; |
if (*p == '.') |
getSz(&sz); |
|
Rt = getRegisterX(); |
need(','); |
if (oc==4) { |
Rt = getRegisterX(); |
need(','); |
p = inptr; |
Ra = getRegisterX(); |
if (Ra == -1) { |
inptr = p; |
NextToken(); |
mb = expr(); |
gmb = true; |
} |
need(','); |
p = inptr; |
Rb = getRegisterX(); |
if (Rb == -1) { |
inptr = p; |
NextToken(); |
me = expr(); |
gme = true; |
} |
need(','); |
p = inptr; |
Rc = getRegisterX(); |
if (Rc == -1) { |
inptr = p; |
NextToken(); |
val = expr(); |
Ra = 0; |
gval = true; |
} |
else { |
val = 0LL; |
Ra = getRegisterX(); |
} |
need(','); |
NextToken(); |
mb = expr(); |
need(','); |
NextToken(); |
me = expr(); |
emit_insn( |
(oc << 34LL) | |
(me << 27LL) | |
(sz << 24) | |
(mb << 18) | |
(Rt << 12) | |
((Ra|(val & 0x3f)) << 6) | |
0x22,!expand_flag,5 |
); |
op = |
(oc << 44LL) | |
((gval?1LL:0LL) << 32LL) | |
((gme?1LL:0LL) << 31LL) | |
((gmb?1:0) << 30) | |
(Rt << 23) | |
(1 << 6) | |
0x22; |
if (gmb) |
op |= ((mb & 31) << 8) | (((mb >> 5) & 1) << 28); |
else |
op |= (Ra << 8); |
if (gme) |
op |= ((me & 31) << 13) | (((me >> 5) & 1) << 29); |
else |
op |= (Rb << 13); |
if (gval) |
op |= ((val & 31) << 18) | (((val >> 5) & 0x7ff) << 33LL); |
else |
op |= (Rc << 18); |
|
emit_insn(op, 0, 6); |
ScanToEOL(); |
} |
|
|
2477,24 → 2518,26
{ |
int Ra = 0, Rb = 0; |
int64_t val; |
int64_t disp; |
int64_t disp, cdisp; |
bool ins48 = false; |
|
NextToken(); |
val = expr(); |
disp = val - (code_address + 4LL); |
cdisp = val - (code_address + 2LL); |
if (!IsNBit(disp, 12)) { |
error("Branch displacement too large"); |
disp = val - (code_address + 6LL); |
ins48 = true; |
} |
disp >>= 1; |
if (disp+1 > -512 && disp+1 < 512) { // disp+1 accounts for instruction size of 2 not 4 |
disp++; |
cdisp >>= 1; |
if (cdisp > -512 && cdisp < 512) { // disp+1 accounts for instruction size of 2 not 4 |
emit_insn( |
(7 << 12) | |
(((disp >> 6) & 0xf) << 8) | |
(((cdisp >> 6) & 0xf) << 8) | |
(2 << 6) | |
(disp & 0x3f), 0, 2 |
(cdisp & 0x3f), 0, 2 |
); |
return; |
} |
2768,7 → 2811,7
if (neg) incamt = -incamt; |
if (Rb >= 0) { |
if (disp != 0) |
printf("displacement not allowed with indexed addressing.\r\n"); |
error("displacement not allowed with indexed addressing"); |
oc = 0x1A; // INCX |
// ToDo: fix this |
emit_insn( |
3190,19 → 3233,19
|
static void process_ldi() |
{ |
int Ra = 0; |
int Rt; |
int64_t val; |
int Ra = 0; |
int Rt; |
int64_t val; |
char *p; |
int sz = 3; |
|
p = inptr; |
p = inptr; |
if (*p=='.') |
getSz(&sz); |
sz &= 3; |
Rt = getRegisterX(); |
expect(','); |
val = expr(); |
Rt = getRegisterX(); |
expect(','); |
val = expr(); |
if (IsNBit(val, 5) && Rt != 0) { |
emit_insn( |
(1 << 12) | |
4522,6 → 4565,16
case tk_eor: process_rrop(0x0A,0x0A); break; |
case tk_eori: process_riop(0x0A); break; |
case tk_extern: process_extern(); break; |
case tk_file: |
NextToken(); |
if (token==tk_strconst) |
mname = std::string(laststr); |
//NextToken(); |
//if (token == ',') { |
// NextToken(); |
// lineno = expr(); |
//} |
break; |
case tk_ftoi: process_ftoi(0x12); break; |
case tk_fadd: process_fprrop(0x04); break; |
case tk_fbeq: process_fbcc(0); break; |
4565,6 → 4618,7
case tk_lvw: ProcessLoadVolatile(0x3B,8); break; |
case tk_lw: process_load(0x20,4); break; |
case tk_lwr: process_load(0x1D,0); break; |
case tk_macro: process_macro(); break; |
case tk_memdb: emit_insn(0x04400002,0,4); break; |
case tk_memsb: emit_insn(0x04440002,0,4); break; |
case tk_message: process_message(); break; |
/trunk/FT64v5/software/AS64/source/Macro.cpp
1,32 → 1,37
#include "stdafx.h" |
|
int Macro::inst = 0; |
|
// Substitute the argument list into the macro body. |
|
char *Macro::SubArgs() |
char *Macro::SubArgs(Arglist *al) |
{ |
char *buf, *bdy; |
char *p, *q; |
int ndx; |
static char ibuf[16000]; |
int bufsz; |
|
bdy = body; |
ZeroMemory(ibuf, 16000); |
for (p = ibuf; *bdy; bdy++) { |
buf = new char[16000]; |
ZeroMemory(buf, 16000); |
bufsz = 16000; |
for (p = buf; *bdy; bdy++) { |
// If macro instance indicator found, substitute the instance number. |
if (*bdy == '@') |
p += sprintf_s(p, 16000 - (p-buf), "%d", inst); |
if (*bdy == '@') { |
p += sprintf_s(p, bufsz - (p - buf), "%d", inst); |
*p = '\0'; |
} |
else if (*bdy == MACRO_PARM_MARKER) { |
if (isdigit(*(bdy+1))) { |
bdy++; |
ndx = *bdy - '0'; |
if (ndx < args->count) { |
// Copy the argument from the arg list to the output buffer. |
for (q = args->arg[ndx]->text; *q; q++) { |
*p = *q; |
p++; |
if (ndx < parms.count && ndx < al->count) { |
// Copy the parameter from the arg list to the output buffer. |
if (&buf[bufsz] - p > al->args[ndx].text.length()) { |
strcpy(p, (char *)al->args[ndx].text.c_str()); |
while (*p) p++; |
} |
} |
printf("Not enough args for substitution. %d\r\n", lineno); |
} |
else { |
*p = *bdy; |
38,13 → 43,86
*p = *bdy; |
p++; |
} |
if (&buf[bufsz] - p < 20) { |
ndx = p - buf; |
q = new char[bufsz + 10000]; |
memcpy(q, buf, bufsz); |
bufsz += 10000; |
delete[] buf; |
buf = q; |
p = &buf[ndx]; |
} |
} |
buf = new char[strlen(ibuf)+1]; |
memcpy(buf, ibuf, strlen(ibuf)+1); |
*p = '\0'; |
return (buf); |
} |
|
|
void SkipBlockComment() |
{ |
char c; |
|
do { |
c = *inptr; |
inptr++; |
if (c == '*') { |
c = *inptr; |
inptr++; |
if (c == '/') |
break; |
--inptr; |
} |
} while (c > 0); |
} |
|
int ProcessUnquoted() |
{ |
char c; |
|
c = *inptr; |
if (c == '/') { |
c = *inptr; |
inptr++; |
c = *inptr; |
inptr++; |
// Block comment ? |
if (c == '*') { |
SkipBlockComment(); |
c = *inptr; |
if (c > 0) |
return (1); |
else { |
printf("End of file in block comment. %d\n", lineno); |
return (0); |
} |
} |
// Comment to EOL ? |
else if (c == '/') { |
ScanToEOL(); |
c = *inptr; |
if (c > 0) |
return (0); |
} |
else { |
c = '/'; |
--inptr; |
} |
} |
return (1); |
} |
|
int CountLeadingSpaces() |
{ |
int count; |
|
count = 0; |
while (*inptr == ' ' || *inptr == '\t') { |
inptr++; |
count++; |
} |
return (count); |
} |
|
// --------------------------------------------------------------------------- |
// Description : |
// Gets the body of a macro. All macro bodies must be < 2k in size. Macro |
55,130 → 133,130
// newline is removed from the macro. |
// ---------------------------------------------------------------------------- |
|
char *Macro::GetBody(char *parmlist[]) |
char *Macro::GetBody() |
{ |
char *b, *id = NULL, *p1, *p2; |
static char buf[16000]; |
int ii, found, c; |
int InQuote = 0; |
int count = sizeof(buf)-1; |
char *b, *id = NULL, *p1, *p2; |
char *buf; |
int ii, found, c; |
int InQuote = 0; |
int count = 16000; |
bool abort = false; |
|
SkipSpaces(); |
memset(buf, 0, sizeof(buf)); |
for (b = buf; count >= 0; b++, --count) |
{ |
// First search for an identifier to substitute with parameter |
if (parmlist) { |
while (*inptr == ' ' || *inptr == '\t') { |
*b++ = *inptr; |
inptr++; |
count--; |
if (count < 0) |
goto jmp1; |
} |
p1 = inptr; |
id = getIdentifier(); |
p2 = inptr; |
if (id) { |
for (found = ii = 0; parmlist[ii]; ii++) |
if (strcmp(parmlist[ii], id) == 0) { |
*b = ''; |
b++; |
count--; |
if (count < 0) |
goto jmp1; |
*b = '0' + (char)ii; |
found = 1; |
break; |
} |
// if the identifier was not a parameter then just copy it to |
// the macro body |
if (!found) { |
strncpy(b, p1, p2-p1); |
count -= p2 -p1 - 1; |
if (count < 0) |
goto jmp1; |
b += p2-p1-1; // b will be incremented at end of loop |
} |
} |
else |
inptr = p1; // reset inptr if no identifier found |
} |
if (id == NULL) { |
c = *inptr; |
inptr++; |
if (c == '"') |
InQuote = !InQuote; |
if (!InQuote) { |
if (c == '/') { |
try { |
buf = new char[count]; |
ZeroMemory(buf, count); |
SkipSpaces(); |
for (b = buf; count >= 0; ) |
{ |
// First search for an identifier to substitute with parameter |
if (parms.count > 0) { |
ii = CountLeadingSpaces(); |
count -= ii; |
if (count < 0) |
break; |
memcpy(b, inptr - ii, ii); |
b += ii; |
p1 = inptr; |
NextToken(); |
p2 = inptr; |
if (token == tk_endm) |
break; |
if (token == tk_id) { |
for (found = ii = 0; ii < parms.count && !abort; ii++) { |
if (parms.args[ii].text.compare(lastid) == 0) { |
*b = '\x14'; |
b++; |
count--; |
if (count < 0) { |
abort = true; |
} |
else { |
*b = '0' + (char)ii; |
b++; |
found = 1; |
break; |
} |
} |
} |
if (abort) |
break; |
// if the identifier was not a parameter then just copy it to |
// the macro body |
if (!found) { |
count -= p2 - p1; |
if (count < 0) |
break; |
memcpy(b, p1, p2 - p1); |
b += p2 - p1; |
} |
} |
else |
inptr = p1; // reset inptr if no identifier found |
} |
if (token == tk_endm) |
break; |
if (token != tk_id) { |
memcpy(b, p1, p2 - p1); |
b += p2 - p1; |
inptr = p2; |
c = *inptr; |
inptr++; |
c = NextCh(); |
// Block comment ? |
if (c == '*') { |
while(c > 0) { |
c = *inptr; |
inptr++; |
if (c == '*') { |
c = *inptr; |
inptr++; |
if (c == '/') |
break; |
--inptr; |
} |
} |
if (c > 0) { |
--b; |
continue; |
} |
else |
printf("End of line in comment. %d\n", lineno); |
} |
// Comment to EOL ? |
else if (c == '/') { |
while(c != '\n' && c > 0) { c = *inptr; inptr++; } |
if (c > 0) { |
--b; |
++count; |
goto jmp1; |
} |
} |
else { |
c = '/'; |
--inptr; |
} |
} |
else if (c == '\\') // check for continuation onto next line |
{ |
while (c != '\n' && c > 0) { c= *inptr; inptr++} |
if (c > 0) { |
--b; // b will be incremented but we haven't got a character |
++count; |
SkipSpaces(); // Skip leading spaces on next line |
continue; |
} |
} |
} |
if (c == '\n' || c < 1) { |
if (InQuote) |
printf("End of file in comment. %d\n", lineno); |
break; |
} |
*b = c; |
} |
} |
jmp1: |
if (count < 0) |
printf("Expanded macro is too large. %d\n", lineno); |
*b = 0; |
rtrim(buf); // Trim off trailing spaces. |
return buf; |
//inptr++; |
if (c == '"') { |
inptr++; |
InQuote = !InQuote; |
} |
if (!InQuote) { |
p1 = inptr; |
c = ProcessUnquoted(); |
if (count - (inptr - p1) < 0) { |
count = -1; |
break; |
} |
memcpy(b, p1, (inptr - p1)); |
b += (inptr - p1); |
if (c == 0) |
break; |
c = inptr[-1]; |
} |
if (c < 1) { |
if (InQuote) |
printf("End of file in quote. %d\n", lineno); |
break; |
} |
} |
} |
|
if (count < 0) { |
delete[] buf; |
printf("Expanded macro is too large. %d\n", lineno); |
body = new char[20]; |
strcpy(body, "<too large>"); |
return (body); |
} |
else { |
*b = '\0'; |
--b; |
// Trim off trailing spaces. |
while ((*b == ' ' || *b == '\t') && b > buf) { |
b--; |
} |
b++; |
*b = '\0'; |
body = new char[strlen(buf) + 10]; |
strcpy(body, buf); |
delete[] buf; |
return (body); |
} |
} |
catch (...) { |
printf("Thrown error\n"); |
} |
} |
|
|
void Arg::Clear() |
{ |
ZeroMemory(text,sizeof(text)); |
text = ""; |
} |
|
// --------------------------------------------------------------------------- |
191,44 → 269,44
|
void Arg::Get() |
{ |
int Depth = 0; |
int c; |
char *argstr = text; |
int Depth = 0; |
int c; |
char ch; |
char *st; |
|
SkipSpaces(); |
ZeroMemory(text,sizeof(text)); |
while(1) |
{ |
if (argstr-text > sizeof(text)-2) { |
printf("Macro argument too large %d. Is a ')' missing ?\n",lineno); |
break; |
} |
c = *inptr; |
SkipSpaces(); |
st = inptr; |
while(1) |
{ |
c = *inptr; |
inptr++; |
if (c < 1) { |
if (Depth > 0) |
printf("err16\r\n"); |
break; |
} |
if (c == '(') |
Depth++; |
else if (c == ')') { |
if (Depth < 1) { // check if we hit the end of the arg list |
--inptr; |
break; |
} |
Depth--; |
} |
else if (Depth == 0 && c == ',') { // comma at outermost level means |
--inptr; |
break; // end of argument has been found |
} |
else if (Depth == 0 && (c=='\r' || c=='\n')) { |
--inptr; |
break; |
if (c < 1) { |
if (Depth > 0) |
printf("err16\r\n"); |
break; |
} |
if (c == '(') |
Depth++; |
else if (c == ')') { |
if (Depth < 1) { // check if we hit the end of the arg list |
--inptr; |
break; |
} |
Depth--; |
} |
else if (Depth == 0 && c == ',') { // comma at outermost level means |
--inptr; |
break; // end of argument has been found |
} |
else if (Depth == 0 && (c=='\r' || c=='\n')) { |
--inptr; |
break; |
} |
*argstr++ = c; // copy input argument to argstr. |
} |
ch = *inptr; |
*inptr = '\0'; |
text = std::string(st); |
*inptr = ch; |
// if (argbuf[0]) |
// if (fdbg) fprintf(fdbg," macro arg<%s>\r\n",argbuf); |
return; |
238,28 → 316,48
{ |
int nn; |
char lastch; |
bool done = false; |
|
for (nn = 0; nn < 10; nn++) |
args[nn]->Clear(); |
for (nn = 0; nn < 10; nn++) { |
args[nn]->Get(); |
if (*inptr != ',') { |
SkipSpaces(); |
break; |
args[nn].Clear(); |
count = 0; |
j1: |
SkipSpaces(); |
switch (*inptr) { |
case '\n': |
lineno++; |
case '\r': |
inptr++; |
goto j1; |
case '(': |
inptr++; |
SkipSpaces(); |
for (; count < 10 && !done; count++) { |
args[count].Get(); |
switch (*inptr) { |
// Arg list can continue on next line |
case '\n': |
lineno++; |
case '\r': |
inptr++; |
continue; |
case ')': |
done = true; |
inptr++; |
break; |
case ',': |
inptr++; |
SkipSpaces(); |
continue; |
case '\0': |
break; |
default: |
inptr++; |
} |
} |
inptr++; // skip over , |
break; |
default:; |
} |
args->count = nn; |
while (*inptr) { |
if (*inptr==0) |
break; |
if (*inptr=='\n') { |
lineno++; |
inptr++; |
break; |
} |
inptr++; |
} |
} |
|
// --------------------------------------------------------------------------- |
271,25 → 369,23
// pointer to first parameter in list. |
// ---------------------------------------------------------------------------- |
|
int Macro::GetParmList(char *parmlist[]) |
int Macro::GetParmList() |
{ |
int id; |
int Depth = 0, c, count; |
int id; |
int Depth = 0, c; |
|
count = 0; |
while(1) |
{ |
id = getIdentifier(); |
if (id!=0) { |
if (count >= 20) { |
printf("Too many macro parameters %d.\n", lineno); |
goto errxit; |
} |
parmlist[count] = _strdup(lastid); |
if (parmlist[count] == NULL) |
printf("Insufficient memory %d\n", lineno); |
count++; |
} |
parms.count = 0; |
while(1) |
{ |
NextToken(); |
if (token==tk_id) { |
if (parms.count >= 20) { |
printf("Too many macro parameters %d.\n", lineno); |
goto errxit; |
} |
parms.args[parms.count].text = std::string(lastid); |
parms.count++; |
} |
do { |
SkipSpaces(); |
c = *inptr; |
300,21 → 396,17
} |
} |
while (c=='\\'); |
if (c == ')') { // we've gotten our last parameter |
inptr--; |
break; |
} |
if (c != ',') { |
printf("Expecting ',' in macro parameter list %d.\n", lineno); |
goto errxit; |
} |
} |
// if (count < 1) |
// err(17); |
if (count < 20) |
parmlist[count] = NULL; |
if (c == ')') { // we've gotten our last parameter |
inptr--; |
break; |
} |
if (c != ',') { |
printf("Expecting ',' in macro parameter list %d.\n", lineno); |
goto errxit; |
} |
} |
errxit:; |
return count; |
return (parms.count); |
} |
|
|
326,17 → 418,25
// slen; - the number of characters being substituted |
// ----------------------------------------------------------------------------- |
|
void Macro::Substitute(char *body, int slen) |
void Macro::Substitute(char *what, int slen) |
{ |
int mlen, dif, nchars; |
int nn; |
char *p; |
int mlen, dif, nchars; |
int nn; |
char *p; |
|
mlen = strlen(body); // macro length |
dif = mlen - slen; |
nchars = inptr-masterFile; // calculate number of characters that could be remaining |
memmove(inptr+dif, inptr, sizeof(masterFile)-500-nchars-dif); // shift open space in input buffer |
inptr -= slen; // reset input pointer to start of replaced text |
memcpy(inptr, body, mlen); // copy macro body in place over identifier |
mlen = strlen(what); // macro length |
dif = mlen - slen; |
nchars = inptr - masterFile; // calculate number of characters that could be remaining |
if (dif > 10000) { |
p = new char[masterFileLength + dif + 10000]; |
memcpy(p, masterFile, masterFileLength); |
masterFile = p; |
masterFileLength = masterFileLength + dif + 10000; |
inptr = &masterFile[nchars]; |
} |
memmove(inptr+dif, inptr, masterFileLength-500-nchars-dif); // shift open space in input buffer |
inptr -= slen; // reset input pointer to start of replaced text |
memcpy(inptr, what, mlen); // copy macro body in place over identifier |
inst++; |
} |
|
/trunk/FT64v5/software/AS64/source/a64.h
56,8 → 56,11
extern int segmodel; |
extern SHashTbl HashInfo; |
|
extern FilenameStack fns; |
extern std::string mname; |
extern int gCpu; |
extern char lastid[500]; |
extern char laststr[500]; |
extern char current_label[500]; |
extern Int128 last_icon; |
extern Int128 ival; |
69,7 → 72,8
extern int64_t bss_address; |
extern int64_t data_address; |
extern int segprefix; |
extern char masterFile[10000000]; |
extern int masterFileLength; |
extern char *masterFile; |
extern uint8_t binfile[10000000]; |
extern int binndx; |
extern int64_t binstart; |
/trunk/FT64v5/software/AS64/source/main.cpp
27,6 → 27,8
|
#define MAX_PASS 6 |
|
FilenameStack fns; |
|
int gCpu = 888; |
int verbose = 1; |
int debug = 1; |
58,12 → 60,16
int64_t bss_address; |
int64_t start_address; |
FILE *ofp, *vfp; |
std::ofstream mofs; |
|
int regno; |
char first_org = 1; |
char current_label[500]; |
|
std::string mname; |
char buf[10000]; |
char masterFile[10000000]; |
int masterFileLength = 0; |
char *masterFile; |
char segmentFile[10000000]; |
int NumSections = 12; |
clsElf64Section sections[12]; |
115,6 → 121,12
extern void SymbolInit(); |
extern void dsd9_VerilogOut(FILE *fp); |
|
Arg gArgs[12]; |
int gArgCount; |
Arglist gArglist; |
|
FILE *mfp; // master file pointer |
|
// --------------------------------------------------------------------------- |
// --------------------------------------------------------------------------- |
|
562,17 → 574,17
} |
else { |
if (first_org && segment==codeseg) { |
program_address = new_address; |
code_address = new_address; |
start_address = new_address*mul; |
sections[0].address = new_address*mul; |
first_org = 0; |
program_address = new_address; |
code_address = new_address; |
start_address = new_address*mul; |
sections[0].address = new_address*mul; |
first_org = 0; |
} |
else { |
// Ignore the org directive in initialized data area of rodata |
if (!isInitializationData) |
while(sections[0].address < new_address*mul) |
emitByte(0x00); |
// Ignore the org directive in initialized data area of rodata |
if (!isInitializationData) |
while(sections[0].address < new_address*mul) |
emitByte(0x00); |
} |
} |
} |
1030,7 → 1042,60
} |
|
// --------------------------------------------------------------------------- |
// macro <name> (<arg1, arg2, arg3, ...>) |
// < macro body > |
// endm |
// --------------------------------------------------------------------------- |
|
void process_macro() |
{ |
SYM *sym; |
Macro *macr; |
bool alreadyDef = false; |
char *p; |
|
if (pass == 3) { |
macr = new Macro; |
SkipSpaces(); |
getIdentifier(); |
sym = find_symbol(lastid); |
if (sym != nullptr) { |
printf("Macro already defined %d.", lineno); |
alreadyDef = true; |
} |
else { |
sym = new_symbol(lastid); |
sym->defined = 1; |
sym->isMacro = true; |
sym->macro = macr; |
} |
NextToken(); |
if (token == '(') { |
macr->GetParmList(); |
NextToken(); |
need(')'); |
} |
p = inptr; |
macr->GetBody(); |
if (alreadyDef) |
delete macr; |
} |
else if (pass > 3) { |
Macro mthrowaway; |
SkipSpaces(); |
getIdentifier(); |
NextToken(); |
if (token == '(') { |
mthrowaway.GetParmList(); |
NextToken(); |
need(')'); |
} |
mthrowaway.GetBody(); |
} |
} |
|
// --------------------------------------------------------------------------- |
// --------------------------------------------------------------------------- |
void process_message() |
{ |
char buf[200]; |
1057,12 → 1122,12
|
void process_label() |
{ |
SYM *sym; |
static char nm[500]; |
int64_t ca; |
Int128 val; |
int isEquate; |
int shft = 0; |
SYM *sym; |
static char nm[500]; |
int64_t ca; |
Int128 val; |
int isEquate; |
int shft = 0; |
|
val.low = 0; |
val.high = 0; |
1216,65 → 1281,89
|
void processSegments() |
{ |
char *pinptr; |
int segment = codeseg; |
int inComment; |
|
if (verbose) |
printf("Processing segments.\r\n"); |
inptr = &masterFile[0]; |
pinptr = inptr; |
codendx = 0; |
datandx = 0; |
rodatandx = 0; |
tlsndx = 0; |
bssndx = 0; |
memset(codebuf,0,sizeof(codebuf)); |
memset(databuf,0,sizeof(databuf)); |
memset(rodatabuf,0,sizeof(rodatabuf)); |
memset(tlsbuf,0,sizeof(tlsbuf)); |
memset(bssbuf,0,sizeof(bssbuf)); |
inComment = 0; |
char *pinptr; |
int segment = codeseg; |
int inComment; |
std::string fname; |
bool setname = false; |
|
if (verbose) |
printf("Processing segments.\r\n"); |
inptr = &masterFile[0]; |
pinptr = inptr; |
codendx = 0; |
datandx = 0; |
rodatandx = 0; |
tlsndx = 0; |
bssndx = 0; |
ZeroMemory(codebuf,sizeof(codebuf)); |
ZeroMemory(databuf,sizeof(databuf)); |
ZeroMemory(rodatabuf,sizeof(rodatabuf)); |
ZeroMemory(tlsbuf,sizeof(tlsbuf)); |
ZeroMemory(bssbuf,sizeof(bssbuf)); |
inComment = 0; |
|
while (*inptr) { |
SkipSpaces(); |
if (*inptr==';') |
goto j1; |
if (inptr[0]=='/' && inptr[1]=='/') |
goto j1; |
// if (inptr[0]=='/' && inptr[1]=='*') { |
// inComment = 1; |
// goto j1; |
// } |
// if (inComment && inptr[0]=='*' && inptr[1]=='/') |
// inComment = 0; |
// if (inComment) |
// goto j1; |
if (*inptr=='.') inptr++; |
if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) { |
segment = codeseg; |
} |
else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) { |
segment = dataseg; |
} |
else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) { |
segment = rodataseg; |
} |
else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) { |
segment = tlsseg; |
} |
else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) { |
segment = bssseg; |
} |
lineno = 1; |
while (*inptr) { |
if (*inptr == '\n') |
lineno++; |
SkipSpaces(); |
if (*inptr == ';') |
goto j1; |
if (inptr[0] == '/' && inptr[1] == '/') |
goto j1; |
// if (inptr[0]=='/' && inptr[1]=='*') { |
// inComment = 1; |
// goto j1; |
// } |
// if (inComment && inptr[0]=='*' && inptr[1]=='/') |
// inComment = 0; |
// if (inComment) |
// goto j1; |
if (*inptr == '.') inptr++; |
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) { |
inptr += 4; |
NextToken(); |
if (token == tk_strconst) |
fname = std::string(laststr); |
else |
fname = std::string("<unknown file>"); |
NextToken(); |
lineno = expr(); |
setname = true; |
} |
else if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) { |
segment = codeseg; |
setname = true; |
} |
else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) { |
segment = dataseg; |
} |
else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) { |
segment = rodataseg; |
} |
else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) { |
segment = tlsseg; |
} |
else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) { |
segment = bssseg; |
} |
j1: |
ScanToEOL(); |
inptr++; |
switch(segment) { |
case codeseg: |
strncpy(&codebuf[codendx], pinptr, inptr-pinptr); |
codendx += inptr-pinptr; |
break; |
case dataseg: |
if (setname) { |
setname = false; |
if (fname.length() > 0) { |
sprintf(&codebuf[codendx], ".file \x22%s\x22,%d\n", fname.c_str(), lineno); |
codendx += strlen(&codebuf[codendx]); |
} |
} |
strncpy(&codebuf[codendx], pinptr, inptr-pinptr); |
codendx += inptr-pinptr; |
break; |
case dataseg: |
strncpy(&databuf[datandx], pinptr, inptr-pinptr); |
datandx += inptr-pinptr; |
break; |
1293,7 → 1382,7
} |
pinptr = inptr; |
} |
memset(masterFile,0,sizeof(masterFile)); |
ZeroMemory(masterFile,sizeof(masterFile)); |
strcat(masterFile, codebuf); |
strcat(masterFile, rodatabuf); |
strcat(masterFile, "\r\n\trodata\r\n"); |
1316,6 → 1405,103
} |
} |
|
void ProcessSegments2() |
{ |
char buf[1000]; |
char *lptr; |
char fname[600]; |
bool setname = false; |
|
std::ifstream ifs("as64-master.asm"); |
std::ofstream codeofs("as64-code.asm"); |
std::ofstream dataofs("as64-data.asm"); |
std::ofstream idataofs("as64-idata.asm"); |
std::ofstream rodataofs("as64-rodata.asm"); |
std::ofstream bssofs("as64-bss.asm"); |
std::ofstream tlsofs("as64-tls.asm"); |
|
ZeroMemory(buf, sizeof(buf)); |
ZeroMemory(fname, sizeof(fname)); |
while (ifs.getline(buf, sizeof(buf))) { |
inptr = buf; |
SkipSpaces(); |
if (*inptr == ';') |
goto j1; |
if (inptr[0] == '/' && inptr[1] == '/') |
goto j1; |
if (*inptr == '.') inptr++; |
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) { |
inptr += 4; |
if (inptr[0] == ':') |
inptr++; |
getIdentifier(); |
strcpy_s(fname, sizeof(fname), lastid); |
} |
if ((_strnicmp(inptr, "code", 4) == 0) && !isIdentChar(inptr[4])) { |
segment = codeseg; |
setname = true; |
} |
else if ((_strnicmp(inptr, "data", 4) == 0) && !isIdentChar(inptr[4])) { |
segment = dataseg; |
} |
else if ((_strnicmp(inptr, "rodata", 6) == 0) && !isIdentChar(inptr[6])) { |
segment = rodataseg; |
} |
else if ((_strnicmp(inptr, "tls", 3) == 0) && !isIdentChar(inptr[3])) { |
segment = tlsseg; |
} |
else if ((_strnicmp(inptr, "bss", 3) == 0) && !isIdentChar(inptr[3])) { |
segment = bssseg; |
} |
j1: |
switch (segment) { |
case codeseg: |
if (setname) { |
setname = false; |
codeofs << ".file: "; |
codeofs << fname; |
} |
codeofs << buf; |
break; |
case dataseg: |
dataofs << buf; |
break; |
case rodataseg: |
rodataofs << buf; |
break; |
case tlsseg: |
tlsofs << buf; |
break; |
case bssseg: |
bssofs << buf; |
break; |
} |
} |
codeofs.close(); |
dataofs.close(); |
idataofs.close(); |
rodataofs.close(); |
bssofs.close(); |
tlsofs.close(); |
ifs.close(); |
system("type as64-code.asm > as64-segments.asm"); |
system("type as64-rodata.asm >> as64-segments.asm"); |
std::ofstream ofs("as64-segments.asm", std::ofstream::out | std::ofstream::app); |
ofs << "\nrodata\n"; |
ofs << "\talign 8\n"; |
ofs << "begin_init_data:\n"; |
ofs.close(); |
system("type as64-data.asm >> as64-segments.asm"); |
ofs.open("as64-segments.asm", std::ofstream::out | std::ofstream::app); |
ofs << "\nrodata\n"; |
ofs << "\talign 8\n"; |
ofs << "end_init_data:\n"; |
ofs.close(); |
system("type as64-data.asm >> as64-segments.asm"); |
system("type as64-bss.asm >> as64-segments.asm"); |
system("type as64-tls.asm >> as64-segments.asm"); |
} |
|
void skipif(int64_t val) |
{ |
int iflevel = 1; |
1416,47 → 1602,49
|
void processLine(char *line) |
{ |
char *p; |
int quoteType; |
static char fnm[300]; |
char *fname; |
int nn; |
int lb; |
char *p; |
int quoteType; |
static char fnm[300]; |
char *fname; |
int nn; |
int lb; |
|
p = line; |
p = line; |
fns.GetTos()->lineno = lineno; |
while(isspace(*p)) p++; |
if (!*p) goto addToMaster; |
// see if the first thing on the line is an include directive |
if (*p=='.') p++; |
if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7])) |
{ |
p += 7; |
// Capture the file name |
while(isspace(*p)) p++; |
if (!*p) goto addToMaster; |
// see if the first thing on the line is an include directive |
if (*p=='.') p++; |
if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7])) |
{ |
p += 7; |
// Capture the file name |
while(isspace(*p)) p++; |
if (*p=='"') { quoteType = '"'; p++; } |
else if (*p=='<') { quoteType = '>'; p++; } |
else quoteType = ' '; |
nn = 0; |
do { |
fnm[nn] = *p; |
p++; nn++; |
if (quoteType==' ' && isspace(*p)) break; |
else if (*p == quoteType) break; |
else if (*p=='\n') break; |
} while(nn < sizeof(fnm)/sizeof(char)); |
fnm[nn] = '\0'; |
fname = strdup(fnm); |
lb = lineno; |
lineno = 1; |
processFile(fname,1); |
lineno = lb; |
free(fname); |
return; |
} |
// Not an include directive, then just copy the line to the master buffer. |
if (*p=='"') { quoteType = '"'; p++; } |
else if (*p=='<') { quoteType = '>'; p++; } |
else quoteType = ' '; |
nn = 0; |
do { |
fnm[nn] = *p; |
p++; nn++; |
if (quoteType==' ' && isspace(*p)) break; |
else if (*p == quoteType) break; |
else if (*p=='\n') break; |
} while(nn < sizeof(fnm)/sizeof(char)); |
fnm[nn] = '\0'; |
fname = strdup(fnm); |
lb = lineno; |
lineno = 1; |
processFile(fname,1); |
lineno = lb; |
free(fname); |
return; |
} |
// Not an include directive, then just copy the line to the master buffer. |
addToMaster: |
strcpy(&masterFile[mfndx], line); |
mfndx += strlen(line); |
//strcpy(&masterFile[mfndx], line); |
//mfndx += strlen(line); |
mofs << line; |
} |
|
// ---------------------------------------------------------------------------- |
1465,34 → 1653,45
|
void processFile(char *fname, int searchincl) |
{ |
FILE *fp; |
char *pathname; |
FILE *fp; |
std::ifstream ifs; |
char *pathname; |
char buf[700]; |
|
if (verbose) |
printf("Processing file:%s\r\n", fname); |
pathname = (char *)NULL; |
fp = fopen(fname, "r"); |
if (!fp) { |
if (searchincl) { |
searchenv(fname, "INCLUDE", &pathname); |
if (strlen(pathname)) { |
fp = fopen(pathname, "r"); |
if (fp) goto j1; |
} |
} |
printf("Can't open file <%s>\r\n", fname); |
goto j2; |
} |
fns.Push(mname, lineno); |
mname = std::string(fname); |
lineno = 1; |
mofs << ".file \x22"; |
mofs << mname.c_str(); |
mofs << "\x22," << lineno << "\n"; |
if (verbose) |
printf("Processing file:%s\n", fname); |
pathname = (char *)NULL; |
ifs.open(fname); |
if (ifs.fail()) { |
if (searchincl) { |
searchenv(fname, "INCLUDE", &pathname); |
if (strlen(pathname)) { |
ifs.open(pathname); |
if (!ifs.fail()) goto j1; |
} |
} |
printf("Can't open file <%s>\n", fname); |
goto j2; |
} |
j1: |
while (!feof(fp)) { |
fgets(buf, sizeof(buf)/sizeof(char), fp); |
processLine(buf); |
ZeroMemory(buf,sizeof(buf)); |
} |
fclose(fp); |
while (ifs.getline(buf, sizeof(buf))) { |
strcat(buf,"\n"); |
processLine(buf); |
} |
ifs.close(); |
j2: |
if (pathname) |
free(pathname); |
if (pathname) |
free(pathname); |
fns.Pop(&mname, &lineno); |
mofs << ".file \x22"; |
mofs << mname.c_str(); |
mofs << "\x22," << lineno << "\n"; |
} |
|
// ---------------------------------------------------------------------------- |
1527,7 → 1726,7
|
void processMaster() |
{ |
expandedBlock = 0; |
expandedBlock = 0; |
switch(gCpu) { |
case 888: Table888_processMaster(); break; |
case 889: Table888mmu_processMaster(); break; |
1869,57 → 2068,66
|
int main(int argc, char *argv[]) |
{ |
int nn,qq,kk; |
static char fname[500]; |
static char hexbuf[500]; |
char *p; |
uint64_t lsa; // last start address |
double bpi; |
int64_t i64; |
uint32_t u32; |
int nn,qq,kk; |
static char fname[500]; |
static char hexbuf[500]; |
char *p; |
uint64_t lsa; // last start address |
double bpi; |
int64_t i64; |
uint32_t u32; |
float nc2; |
std::ifstream ifs; |
|
processOpt = 1; |
processOpt = 1; |
sections[bssseg].storebyte = 0; |
ofp = stdout; |
nn = processOptions(argc, argv); |
if (nn > argc-1) { |
displayHelp(); |
return 0; |
} |
SymbolInit(); |
strcpy_s(fname, sizeof(fname), argv[nn]); |
mfndx = 0; |
start_address = 0; |
code_address = 0; |
bss_address = 0; |
data_address = 0; |
isInitializationData = 0; |
for (qq = 0; qq < 12; qq++) |
sections[qq].Clear(); |
nmTable.Clear(); |
memset(masterFile,0,sizeof(masterFile)); |
if (verbose) printf("Pass 1 - collect all input files.\r\n"); |
ofp = stdout; |
nn = processOptions(argc, argv); |
if (nn > argc-1) { |
displayHelp(); |
return 0; |
} |
SymbolInit(); |
strcpy_s(fname, sizeof(fname), argv[nn]); |
mfndx = 0; |
start_address = 0; |
code_address = 0; |
bss_address = 0; |
data_address = 0; |
isInitializationData = 0; |
for (qq = 0; qq < 12; qq++) |
sections[qq].Clear(); |
nmTable.Clear(); |
mofs.open("as64-master.asm"); |
if (verbose) printf("Pass 1 - collect all input files.\r\n"); |
//PreProcessFile(fname); |
//strcat_s(fname,sizeof(fname),".app.asm"); |
processFile(fname,0); // Pass 1, collect all include files |
if (debug) { |
FILE *fp; |
fopen_s(&fp, "a64-master.asm", "w"); |
if (fp) { |
fwrite(masterFile, 1, strlen(masterFile), fp); |
fclose(fp); |
} |
} |
mname = std::string(fname); |
processFile(fname,0); // Pass 1, collect all include files |
masterFileLength = mofs.tellp(); |
mofs.close(); |
masterFile = new char[masterFileLength + 10000]; |
//if (debug) { |
// FILE *fp; |
// fopen_s(&fp, "a64-master.asm", "w"); |
// if (fp) { |
// fwrite(masterFile, 1, strlen(masterFile), fp); |
// fclose(fp); |
// } |
//} |
ZeroMemory(masterFile, masterFileLength + 10000); |
ifs.open("as64-master.asm"); |
ifs.read(masterFile, masterFileLength + 10000); |
ifs.close(); |
if (verbose) printf("Pass 2 - group and reorder segments\r\n"); |
first_org = 1; |
processSegments(); // Pass 2, group and order segments |
// ProcessSegments2(); |
|
if (verbose) printf("Pass 2 - group and reorder segments\r\n"); |
first_org = 1; |
processSegments(); // Pass 2, group and order segments |
|
pass = 3; |
processMaster(); // Pass 3 collect up opcodes |
printf("Qsorting\r\n"); |
qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp); |
pass = 3; |
processMaster(); // Pass 3 collect up opcodes |
printf("Qsorting\r\n"); |
qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp); |
|
pass = 4; |
if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n"); |
2296,7 → 2504,8
} |
else |
printf("Can't create .hex file.\r\n"); |
return 0; |
delete[] masterFile; |
return (0); |
} |
|
bool IsNBit(int64_t val, int64_t n) |
/trunk/FT64v5/software/AS64/source/proto.h
0,0 → 1,4
#pragma once |
|
void process_macro(); |
|
/trunk/FT64v5/software/AS64/source/stdafx.h
14,6 → 14,7
#include <ctype.h> |
#include <math.h> |
#include <io.h> |
#include <fstream> |
//#include <unistd.h> |
|
#ifndef int64_t |
36,5 → 37,6
#include "token.h" |
#include "symbol.h" |
#include "NameTable.hpp" |
#include "proto.h" |
|
// TODO: reference additional headers your program requires here |
/trunk/FT64v5/software/AS64/source/symbol.cpp
144,6 → 144,7
ts.segment = segment; |
ts.scope = ' '; |
ts.isExtern = 0; |
ts.isMacro = false; |
p = insert_symbol(&ts); |
numsym++; |
return p; |
182,7 → 183,16
for (nn = 0; nn < ii; nn++) { |
// qq = symorder[nn]; |
dp = &pt[nn]; |
if (dp->name) |
if (dp->name && !dp->isMacro) |
fprintf(ofp, "%c %-40s %6s %06llx %d\n", dp->phaserr, nmTable.GetName(dp->name), segname(dp->segment), dp->value.low, dp->bits); |
} |
fprintf(ofp, "\n Macro Name\n"); |
for (nn = 0; nn < ii; nn++) { |
dp = &pt[nn]; |
if (dp->name && dp->isMacro) { |
fprintf(ofp, " %-40s %d\n", nmTable.GetName(dp->name), dp->macro->parms.count); |
fprintf(ofp, "%s", dp->macro->body); |
fprintf(ofp, "\n"); |
} |
} |
} |
/trunk/FT64v5/software/AS64/source/symbol.h
37,6 → 37,8
char isExtern; |
char phaserr; |
char scope; // P = public |
bool isMacro; |
Macro *macro; |
int bits; |
} SYM; |
|
/trunk/FT64v5/software/AS64/source/token.cpp
27,6 → 27,7
|
char *pinptr; |
char lastid[500]; |
char laststr[500]; |
char lastch; |
Int128 last_icon; |
Int128 ival; |
35,22 → 36,25
int my_isspace(char ch) |
{ |
if (ch==' ' || ch=='\t' || ch=='\r') |
return 1; |
return 0; |
return (1); |
return (0); |
} |
int isspaceOrDot(char ch) |
{ |
return my_isspace(ch) || ch=='.'; |
ch &= 0x7f; |
return (my_isspace(ch) || ch=='.'); |
} |
|
int isFirstIdentChar(char ch) |
{ |
return isalpha(ch) || ch=='_'; |
ch &= 0x7f; |
return (isalpha(ch) || ch=='_'); |
} |
|
int isIdentChar(char ch) |
{ |
return isalnum(ch) || ch=='_'; |
ch &= 0x7f; |
return (isalnum(ch) || ch=='_'); |
} |
|
int need(int tk) |
282,57 → 286,71
|
int getIdentifier() |
{ |
int nn; |
int nn; |
|
// printf("GetIdentifier: %.30s\r\n", inptr); |
if (isFirstIdentChar(*inptr) || (*inptr=='.' && isIdentChar(inptr[1]))) { |
nn = 1; |
lastid[0] = *inptr; |
inptr++; |
while(isIdentChar(*inptr) && nn < sizeof(lastid)-1) { |
lastid[nn] = *inptr; |
inptr++; |
nn++; |
} |
lastid[nn] = '\0'; |
return 1; |
if (isFirstIdentChar(*inptr) || (*inptr=='.' && isIdentChar(inptr[1]))) { |
nn = 1; |
lastid[0] = *inptr; |
inptr++; |
while(isIdentChar(*inptr) && nn < sizeof(lastid)-1) { |
lastid[nn] = *inptr; |
inptr++; |
nn++; |
} |
else |
return 0; |
lastid[nn] = '\0'; |
return 1; |
} |
else |
return 0; |
} |
|
void getString() |
{ |
int nn; |
|
nn = 0; |
while (*inptr && *inptr != '"' && *inptr != '\n' && nn < sizeof(laststr) - 2) { |
laststr[nn] = *inptr; |
nn++; |
inptr++; |
} |
inptr++; |
laststr[nn] = '\0'; |
} |
|
static char *pseudos[] = { |
"align", "code", "data", "tls", "rodata", |
"fill", "org", "byte", "message",(char *)NULL |
"align", "code", "data", "tls", "rodata", "file", |
"fill", "org", "byte", "message",(char *)NULL |
}; |
static int pseudoTokens[] = { |
tk_align, tk_code, tk_data, tk_tls, tk_rodata, |
tk_align, tk_code, tk_data, tk_tls, tk_rodata, tk_file, |
tk_fill, tk_org, tk_db, tk_message, tk_none |
}; |
|
int isPseudoOp() |
{ |
static char buf[500]; |
char *p = inptr; |
int nn = 0; |
static char buf[500]; |
char *p = inptr; |
int nn = 0; |
|
if (*p=='.') p++; |
if (!isFirstIdentChar(*p)) |
return 0; |
while(isIdentChar(*p)) { |
buf[nn] = tolower(*p); |
p++; |
nn++; |
if (*p=='.') p++; |
if (!isFirstIdentChar(*p)) |
return (0); |
while(isIdentChar(*p)) { |
buf[nn] = tolower(*p); |
p++; |
nn++; |
} |
buf[nn] = '\0'; |
for (nn = 0; nn < 9; nn++) { |
if (strcmp(buf, pseudos[nn])==0) { |
//inptr = p; |
//token = pseudoTokens[nn]; |
return (1); |
} |
buf[nn] = '\0'; |
for (nn = 0; nn < 8; nn++) { |
if (strcmp(buf, pseudos[nn])==0) { |
//inptr = p; |
//token = pseudoTokens[nn]; |
return 1; |
} |
} |
return 0; |
} |
return (0); |
} |
|
void prevToken() |
342,6 → 360,9
|
int NextToken() |
{ |
char ch; |
char *p; |
|
pinptr = inptr; |
do { |
if (*inptr=='\0') |
351,13 → 372,18
ScanToEOL(); |
continue; |
} |
if (isdigit(*inptr)) { |
ch = *inptr & 0x7f; |
if (isdigit(ch)) { |
getnum(); |
return token; |
} |
switch(*inptr) { |
case '"': |
inptr++; |
getString(); |
return (token = tk_strconst); |
case '.': if (isPseudoOp()) { inptr++; continue; } |
else if (getIdentifier()) { return token = tk_id; } |
else if (getIdentifier()) { return (token = tk_id); } |
else { inptr++; continue; } |
case '\n': inptr++; return token = tk_eol; |
case '$': inptr++; getbase(16); return token = tk_icon; |
1439,6 → 1465,14
return token = tk_ftoi; |
} |
} |
if ((inptr[1] == 'i' || inptr[1] == 'I') && |
(inptr[2] == 'l' || inptr[2] == 'L') && |
(inptr[3] == 'e' || inptr[3] == 'E') && |
(isspace(inptr[4]) || inptr[4] == ':')) { |
inptr += 4; |
return (token = tk_file); |
} |
|
break; |
|
// gran |
2036,12 → 2070,12
} |
} |
if ((inptr[1]=='a' || inptr[1]=='A') && |
(inptr[2]=='r' || inptr[2]=='R') && |
(inptr[3]=='c' || inptr[3]=='C') && |
(inptr[2]=='c' || inptr[2]=='C') && |
(inptr[3]=='r' || inptr[3]=='R') && |
(inptr[4]=='o' || inptr[4]=='O') && |
isspace(inptr[5])) { |
inptr += 5; |
return token = tk_macro; |
return (token = tk_macro); |
} |
break; |
|
2966,12 → 3000,25
} |
// The text wasn't recognized as any of the above tokens. So try for an |
// identifier name. |
p = inptr; |
if (getIdentifier()) { |
return token = tk_id; |
SYM *sym; |
char *q; |
if (sym = find_symbol(lastid)) { |
if (sym->isMacro) { |
Arglist args; |
args.Get(); |
q = sym->macro->SubArgs(&args); |
Macro::Substitute(q, inptr-p); |
inptr = p; |
continue; |
} |
} |
return (token = tk_id); |
} |
inptr++; |
} while (*inptr); |
return token = tk_eof; |
return (token = tk_eof); |
} |
|
// ---------------------------------------------------------------------------- |
/trunk/FT64v5/software/AS64/source/token.h
173,6 → 173,7
tk_fdiv, |
tk_fdx, |
tk_fex, |
tk_file, |
tk_fill, |
tk_fix2flt,//220 |
tk_flt2fix, |
385,6 → 386,7
tk_stcmp, |
tk_stmov, |
tk_stop, |
tk_strconst, |
tk_stset, |
tk_stsb, |
tk_stsc, |
/trunk/FT64v5/software/AS64/source/types.h
4,7 → 4,7
class Arg |
{ |
public: |
char text[120]; |
std::string text; |
public: |
void Get(); |
void Clear(); |
14,7 → 14,7
{ |
public: |
int count; |
Arg args[10]; |
Arg args[20]; |
public: |
void Get(); |
}; |
24,12 → 24,50
public: |
static int inst; |
char *body; // template for macro body |
Arglist parms; |
public: |
char *SubArgs(Arglist *args); |
char *GetArg(); |
char *GetBody(char *parmlist[]); |
int GetParmList(char *[]); |
void Substitute(char *, int); |
char *SubArgs(Arglist *al); |
//char *GetArg(); |
char *GetBody(); |
int GetParmList(); |
static void Substitute(char *, int); |
}; |
|
class FileInfo |
{ |
public: |
std::string name; |
int lineno; |
}; |
|
class FilenameStack |
{ |
public: |
FileInfo stack[21]; |
int sp; |
public: |
FilenameStack() { sp = 0; }; |
void Push(std::string nm, int ln) { |
if (sp > 20) { |
printf("Too many nested files.\n"); |
return; |
} |
stack[sp].name = nm; |
stack[sp].lineno = ln; |
sp++; |
} |
void Pop(std::string *nm, int *ln) { |
if (sp == 0) { |
printf("Filename stack underflow.\n"); |
return; |
} |
--sp; |
*nm = stack[sp].name; |
*ln = stack[sp].lineno; |
} |
FileInfo *GetTos() { |
return (&stack[sp - 1]); |
} |
}; |
|
#endif |