// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2016-2018 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2016-2018 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@finitron.ca
|
// \/_// robfinch<remove>@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// AS64 - Assembler
|
// AS64 - Assembler
|
// - 64 bit CPU
|
// - 64 bit CPU
|
//
|
//
|
// This source file is free software: you can redistribute it and/or modify
|
// This source file is free software: you can redistribute it and/or modify
|
// it under the terms of the GNU Lesser General Public License as published
|
// it under the terms of the GNU Lesser General Public License as published
|
// by the Free Software Foundation, either version 3 of the License, or
|
// by the Free Software Foundation, either version 3 of the License, or
|
// (at your option) any later version.
|
// (at your option) any later version.
|
//
|
//
|
// This source file is distributed in the hope that it will be useful,
|
// This source file is distributed in the hope that it will be useful,
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
#include "stdafx.h"
|
#include "stdafx.h"
|
|
|
#define MAX_PASS 6
|
#define MAX_PASS 6
|
|
|
FilenameStack fns;
|
FilenameStack fns;
|
|
|
int gCpu = 888;
|
int gCpu = 888;
|
int verbose = 1;
|
int verbose = 1;
|
int debug = 1;
|
int debug = 1;
|
int listing = 1;
|
int listing = 1;
|
int binary_out = 1;
|
int binary_out = 1;
|
int verilog_out = 1;
|
int verilog_out = 1;
|
int elf_out = 1;
|
int elf_out = 1;
|
int rel_out = 0;
|
int rel_out = 0;
|
int coe_out = 0;
|
int coe_out = 0;
|
int code_bits = 32;
|
int code_bits = 32;
|
int data_bits = 32;
|
int data_bits = 32;
|
int pass;
|
int pass;
|
int lineno;
|
int lineno;
|
char *inptr;
|
char *inptr;
|
char *stptr;
|
char *stptr;
|
char *pif1, *pif2;
|
char *pif1, *pif2;
|
int token;
|
int token;
|
int phasing_errors;
|
int phasing_errors;
|
int pe1, pe2, pe3;
|
int pe1, pe2, pe3;
|
int bGen = 0;
|
int bGen = 0;
|
bool bGenListing = false;
|
bool bGenListing = false;
|
char fSeg = 0;
|
char fSeg = 0;
|
int segment;
|
int segment;
|
int segprefix = -1;
|
int segprefix = -1;
|
int segmodel = 0;
|
int segmodel = 0;
|
int64_t program_address;
|
int64_t program_address;
|
int64_t code_address;
|
int64_t code_address;
|
int64_t data_address;
|
int64_t data_address;
|
int64_t bss_address;
|
int64_t bss_address;
|
int64_t start_address;
|
int64_t start_address;
|
FILE *ofp, *vfp;
|
FILE *ofp, *vfp;
|
std::ofstream mofs;
|
std::ofstream mofs;
|
|
|
int regno;
|
int regno;
|
char first_org = 1;
|
char first_org = 1;
|
char current_label[500];
|
char current_label[500];
|
|
|
std::string mname;
|
std::string mname;
|
char buf[10000];
|
char buf[10000];
|
int masterFileLength = 0;
|
int masterFileLength = 0;
|
char *masterFile;
|
char *masterFile;
|
char segmentFile[10000000];
|
char segmentFile[10000000];
|
int NumSections = 12;
|
int NumSections = 12;
|
clsElf64Section sections[12];
|
clsElf64Section sections[12];
|
NameTable nmTable;
|
NameTable nmTable;
|
char codebuf[10000000];
|
char codebuf[10000000];
|
char rodatabuf[10000000];
|
char rodatabuf[10000000];
|
char databuf[10000000];
|
char databuf[10000000];
|
char bssbuf[10000000];
|
char bssbuf[10000000];
|
char tlsbuf[10000000];
|
char tlsbuf[10000000];
|
uint8_t binfile[10000000];
|
uint8_t binfile[10000000];
|
uint64_t binfilex36[10000000];
|
uint64_t binfilex36[10000000];
|
int binndx;
|
int binndx;
|
int64_t binstart;
|
int64_t binstart;
|
int mfndx;
|
int mfndx;
|
int codendx;
|
int codendx;
|
int datandx;
|
int datandx;
|
int rodatandx;
|
int rodatandx;
|
int tlsndx;
|
int tlsndx;
|
int bssndx;
|
int bssndx;
|
SYM *lastsym;
|
SYM *lastsym;
|
int isInitializationData;
|
int isInitializationData;
|
float num_bytes;
|
float num_bytes;
|
int num_insns;
|
int num_insns;
|
int num_cinsns;
|
int num_cinsns;
|
HTBLE hTable[100000];
|
HTBLE hTable[100000];
|
int htblmax;
|
int htblmax;
|
int processOpt;
|
int processOpt;
|
int gCanCompress = 1;
|
int gCanCompress = 1;
|
int expandedBlock;
|
int expandedBlock;
|
int expand_flag;
|
int expand_flag;
|
int compress_flag;
|
int compress_flag;
|
int vebits = 128;
|
int vebits = 128;
|
void emitCode(int cd);
|
void emitCode(int cd);
|
void emitAlignedCode(int cd);
|
void emitAlignedCode(int cd);
|
void process_shifti(int oc,int fn);
|
void process_shifti(int oc,int fn);
|
void processFile(char *fname, int searchincl);
|
void processFile(char *fname, int searchincl);
|
void bump_address();
|
void bump_address();
|
extern void Table888_bump_address();
|
extern void Table888_bump_address();
|
extern void searchenv(char *filename, char *envname, char **pathname);
|
extern void searchenv(char *filename, char *envname, char **pathname);
|
extern void Table888mmu_processMaster();
|
extern void Table888mmu_processMaster();
|
extern void Friscv_processMaster();
|
extern void Friscv_processMaster();
|
extern void FISA64_processMaster();
|
extern void FISA64_processMaster();
|
extern void Thor_processMaster();
|
extern void Thor_processMaster();
|
extern void dsd6_processMaster();
|
extern void dsd6_processMaster();
|
extern void dsd7_processMaster();
|
extern void dsd7_processMaster();
|
extern void dsd9_processMaster();
|
extern void dsd9_processMaster();
|
extern void FT64_processMaster();
|
extern void FT64_processMaster();
|
extern void FT64x36_processMaster();
|
extern void FT64x36_processMaster();
|
extern void SymbolInit();
|
extern void SymbolInit();
|
extern void dsd9_VerilogOut(FILE *fp);
|
extern void dsd9_VerilogOut(FILE *fp);
|
|
|
Arg gArgs[12];
|
Arg gArgs[12];
|
int gArgCount;
|
int gArgCount;
|
Arglist gArglist;
|
Arglist gArglist;
|
|
|
FILE *mfp; // master file pointer
|
FILE *mfp; // master file pointer
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void displayHelp()
|
void displayHelp()
|
{
|
{
|
printf("a64 [options] file\r\n");
|
printf("a64 [options] file\r\n");
|
printf(" +v = verbose output\r\n");
|
printf(" +v = verbose output\r\n");
|
printf(" +r = relocatable output\r\n");
|
printf(" +r = relocatable output\r\n");
|
printf(" -s = non-segmented\r\n");
|
printf(" -s = non-segmented\r\n");
|
printf(" +g[n] = cpu version 8=Table888, 9=Table888mmu V=RISCV 6=FISA64 T=Thor\r\n");
|
printf(" +g[n] = cpu version 8=Table888, 9=Table888mmu V=RISCV 6=FISA64 T=Thor\r\n");
|
printf(" D=DSD6 7=DSD7 A=DSD9 F=FT64 G=FT64x36\r\n");
|
printf(" D=DSD6 7=DSD7 A=DSD9 F=FT64 G=FT64x36\r\n");
|
printf(" -o[bvlc] = suppress output file b=binary, v=verilog, l=listing, c=coe\r\n");
|
printf(" -o[bvlc] = suppress output file b=binary, v=verilog, l=listing, c=coe\r\n");
|
}
|
}
|
|
|
int hcmp(const void *a1, const void *b1)
|
int hcmp(const void *a1, const void *b1)
|
{
|
{
|
HTBLE *a = (HTBLE *)a1;
|
HTBLE *a = (HTBLE *)a1;
|
HTBLE *b = (HTBLE *)b1;
|
HTBLE *b = (HTBLE *)b1;
|
return (a->count < b->count) ? 1 : (a->count==b->count) ? 0 : -1;
|
return (a->count < b->count) ? 1 : (a->count==b->count) ? 0 : -1;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void DumphTable()
|
void DumphTable()
|
{
|
{
|
int nn;
|
int nn;
|
HTBLE *pt;
|
HTBLE *pt;
|
|
|
pt = (HTBLE *)hTable;
|
pt = (HTBLE *)hTable;
|
|
|
// Sort the table (already sorted)
|
// Sort the table (already sorted)
|
// qsort(pt, htblmax, sizeof(HTBLE), hcmp);
|
// qsort(pt, htblmax, sizeof(HTBLE), hcmp);
|
|
|
if (gCpu=='F') {
|
if (gCpu=='F') {
|
fprintf(ofp, "%d compressable instructions\n", htblmax);
|
fprintf(ofp, "%d compressable instructions\n", htblmax);
|
fprintf(ofp, "The top 256 are:\n", htblmax);
|
fprintf(ofp, "The top 256 are:\n", htblmax);
|
fprintf(ofp, "Comp Opcode Count\n");
|
fprintf(ofp, "Comp Opcode Count\n");
|
for (nn = 0; nn < htblmax && nn < 256; nn++) {
|
for (nn = 0; nn < htblmax && nn < 256; nn++) {
|
fprintf(ofp, " %03X %012I64X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
|
fprintf(ofp, " %03X %012I64X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
|
}
|
}
|
return;
|
return;
|
}
|
}
|
fprintf(ofp, "%d compressable instructions\n", htblmax);
|
fprintf(ofp, "%d compressable instructions\n", htblmax);
|
fprintf(ofp, "The top 1024 are:\n", htblmax);
|
fprintf(ofp, "The top 1024 are:\n", htblmax);
|
fprintf(ofp, "Comp Opcode Count\n");
|
fprintf(ofp, "Comp Opcode Count\n");
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
|
fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
|
}
|
}
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
int processOptions(int argc, char **argv)
|
int processOptions(int argc, char **argv)
|
{
|
{
|
int nn, mm;
|
int nn, mm;
|
|
|
segmodel = 0;
|
segmodel = 0;
|
nn = 1;
|
nn = 1;
|
do {
|
do {
|
if (nn >= argc-1)
|
if (nn >= argc-1)
|
break;
|
break;
|
if (argv[nn][0]=='-') {
|
if (argv[nn][0]=='-') {
|
if (argv[nn][1]=='o') {
|
if (argv[nn][1]=='o') {
|
mm = 2;
|
mm = 2;
|
while(argv[nn][mm] && !isspace(argv[nn][mm])) {
|
while(argv[nn][mm] && !isspace(argv[nn][mm])) {
|
if (argv[nn][mm]=='b')
|
if (argv[nn][mm]=='b')
|
binary_out = 0;
|
binary_out = 0;
|
else if (argv[nn][mm]=='l')
|
else if (argv[nn][mm]=='l')
|
listing = 0;
|
listing = 0;
|
else if (argv[nn][mm]=='v')
|
else if (argv[nn][mm]=='v')
|
verilog_out = 0;
|
verilog_out = 0;
|
else if (argv[nn][mm]=='e')
|
else if (argv[nn][mm]=='e')
|
elf_out = 0;
|
elf_out = 0;
|
}
|
}
|
}
|
}
|
if (argv[nn][1]=='s')
|
if (argv[nn][1]=='s')
|
fSeg = 0;
|
fSeg = 0;
|
nn++;
|
nn++;
|
}
|
}
|
else if (argv[nn][0]=='+') {
|
else if (argv[nn][0]=='+') {
|
mm = 2;
|
mm = 2;
|
if (argv[nn][1]=='r') {
|
if (argv[nn][1]=='r') {
|
rel_out = 1;
|
rel_out = 1;
|
}
|
}
|
if (argv[nn][1]=='s')
|
if (argv[nn][1]=='s')
|
fSeg = 1;
|
fSeg = 1;
|
if (argv[nn][1]=='g') {
|
if (argv[nn][1]=='g') {
|
if (argv[nn][2]=='9') {
|
if (argv[nn][2]=='9') {
|
gCpu=889;
|
gCpu=889;
|
fSeg = 1;
|
fSeg = 1;
|
}
|
}
|
if (argv[nn][2]=='V') {
|
if (argv[nn][2]=='V') {
|
gCpu = 5;
|
gCpu = 5;
|
}
|
}
|
if (argv[nn][2]=='6') {
|
if (argv[nn][2]=='6') {
|
gCpu = 64;
|
gCpu = 64;
|
}
|
}
|
if (argv[nn][2]=='7') {
|
if (argv[nn][2]=='7') {
|
gCpu = 7;
|
gCpu = 7;
|
if (argv[nn][3]=='c')
|
if (argv[nn][3]=='c')
|
gCanCompress = 1;
|
gCanCompress = 1;
|
else
|
else
|
gCanCompress = 0;
|
gCanCompress = 0;
|
}
|
}
|
if (argv[nn][2]=='T') {
|
if (argv[nn][2]=='T') {
|
gCpu = 4;
|
gCpu = 4;
|
if (argv[nn][3]=='2') {
|
if (argv[nn][3]=='2') {
|
segmodel = 2;
|
segmodel = 2;
|
}
|
}
|
}
|
}
|
if (argv[nn][2]=='D') {
|
if (argv[nn][2]=='D') {
|
gCpu = 14;
|
gCpu = 14;
|
}
|
}
|
if (argv[nn][2]=='A') {
|
if (argv[nn][2]=='A') {
|
gCpu = 'A';
|
gCpu = 'A';
|
if (argv[nn][3]=='c')
|
if (argv[nn][3]=='c')
|
gCanCompress = 1;
|
gCanCompress = 1;
|
else
|
else
|
gCanCompress = 0;
|
gCanCompress = 0;
|
}
|
}
|
if (argv[nn][2]=='F') {
|
if (argv[nn][2]=='F') {
|
gCpu = 'F';
|
gCpu = 'F';
|
mm = 3;
|
mm = 3;
|
gCanCompress = 0;
|
gCanCompress = 0;
|
while(argv[nn][mm]) {
|
while(argv[nn][mm]) {
|
if (argv[nn][mm]=='3')
|
if (argv[nn][mm]=='3')
|
gCpu = 'H';
|
gCpu = 'H';
|
else if (argv[nn][mm]=='c')
|
else if (argv[nn][mm]=='c')
|
gCanCompress = 1;
|
gCanCompress = 1;
|
else if (argv[nn][mm]=='n')
|
else if (argv[nn][mm]=='n')
|
vebits = 64;
|
vebits = 64;
|
mm++;
|
mm++;
|
}
|
}
|
}
|
}
|
if (argv[nn][2]=='G') {
|
if (argv[nn][2]=='G') {
|
gCpu = 'G';
|
gCpu = 'G';
|
if (argv[nn][3]=='n')
|
if (argv[nn][3]=='n')
|
vebits = 64;
|
vebits = 64;
|
else if (argv[nn][3]=='c')
|
else if (argv[nn][3]=='c')
|
gCanCompress = 1;
|
gCanCompress = 1;
|
else
|
else
|
gCanCompress = 0;
|
gCanCompress = 0;
|
}
|
}
|
}
|
}
|
nn++;
|
nn++;
|
}
|
}
|
else break;
|
else break;
|
} while (1);
|
} while (1);
|
return nn;
|
return nn;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// Emit a byte, for DSD7 a byte is 16 bits.
|
// Emit a byte, for DSD7 a byte is 16 bits.
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitByte(int64_t cd)
|
void emitByte(int64_t cd)
|
{
|
{
|
if (segment < 5) {
|
if (segment < 5) {
|
if (gCpu==7)
|
if (gCpu==7)
|
sections[segment].AddChar(cd);
|
sections[segment].AddChar(cd);
|
else
|
else
|
sections[segment].AddByte(cd);
|
sections[segment].AddByte(cd);
|
}
|
}
|
if (segment == codeseg || segment == rodataseg) {
|
if (segment == codeseg || segment == rodataseg) {
|
if (gCpu==7) {
|
if (gCpu==7) {
|
binfile[binndx] = cd & 255LL;
|
binfile[binndx] = cd & 255LL;
|
binndx++;
|
binndx++;
|
binfile[binndx] = (cd >> 8) & 255LL;
|
binfile[binndx] = (cd >> 8) & 255LL;
|
binndx++;
|
binndx++;
|
}
|
}
|
else {
|
else {
|
binfile[binndx] = cd & 255LL;
|
binfile[binndx] = cd & 255LL;
|
binndx++;
|
binndx++;
|
}
|
}
|
}
|
}
|
if (segment==bssseg) {
|
if (segment==bssseg) {
|
bss_address++;
|
bss_address++;
|
}
|
}
|
else if (segment==dataseg)
|
else if (segment==dataseg)
|
data_address++;
|
data_address++;
|
else
|
else
|
code_address++;
|
code_address++;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitNybble(int64_t cd)
|
void emitNybble(int64_t cd)
|
{
|
{
|
static int64_t ln;
|
static int64_t ln;
|
static bool evn = false;
|
static bool evn = false;
|
static int byt = 0;
|
static int byt = 0;
|
|
|
if (cd > 15)
|
if (cd > 15)
|
evn = cd >> 4;
|
evn = cd >> 4;
|
if (!evn) {
|
if (!evn) {
|
emitByte((cd << 4) | ln);
|
emitByte((cd << 4) | ln);
|
}
|
}
|
else
|
else
|
ln = cd;
|
ln = cd;
|
evn = !evn;
|
evn = !evn;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitChar(int64_t cd)
|
void emitChar(int64_t cd)
|
{
|
{
|
emitByte(cd & 255LL);
|
emitByte(cd & 255LL);
|
emitByte((cd >> 8) & 255LL);
|
emitByte((cd >> 8) & 255LL);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitHalf(int64_t cd)
|
void emitHalf(int64_t cd)
|
{
|
{
|
if (gCpu==7) {
|
if (gCpu==7) {
|
emitByte(cd & 65535LL);
|
emitByte(cd & 65535LL);
|
//emitByte((cd >> 16) & 65535LL);
|
//emitByte((cd >> 16) & 65535LL);
|
}
|
}
|
else if (gCpu==5) {
|
else if (gCpu==5) {
|
emitByte(cd & 255LL);
|
emitByte(cd & 255LL);
|
emitByte((cd >> 8) & 255LL);
|
emitByte((cd >> 8) & 255LL);
|
}
|
}
|
else {
|
else {
|
emitChar(cd & 65535LL);
|
emitChar(cd & 65535LL);
|
emitChar((cd >> 16) & 65535LL);
|
emitChar((cd >> 16) & 65535LL);
|
}
|
}
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitWord(int64_t cd)
|
void emitWord(int64_t cd)
|
{
|
{
|
if (gCpu==5 || gCpu==7) {
|
if (gCpu==5 || gCpu==7) {
|
emitHalf(cd & 0xFFFFLL);
|
emitHalf(cd & 0xFFFFLL);
|
emitHalf((cd >> 16) & 0xFFFFLL);
|
emitHalf((cd >> 16) & 0xFFFFLL);
|
}
|
}
|
else {
|
else {
|
emitHalf(cd & 0xFFFFFFFFLL);
|
emitHalf(cd & 0xFFFFFFFFLL);
|
emitHalf((cd >> 32) & 0xFFFFFFFFLL);
|
emitHalf((cd >> 32) & 0xFFFFFFFFLL);
|
}
|
}
|
}
|
}
|
|
|
void emitDecibyte(Int128 cd)
|
void emitDecibyte(Int128 cd)
|
{
|
{
|
emitWord(cd.low);
|
emitWord(cd.low);
|
emitChar(cd.high & 0xFFFFLL);
|
emitChar(cd.high & 0xFFFFLL);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void emitCode(int cd)
|
void emitCode(int cd)
|
{
|
{
|
emitByte(cd);
|
emitByte(cd);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Process a public declaration.
|
// Process a public declaration.
|
// public code myfn
|
// public code myfn
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_public()
|
void process_public()
|
{
|
{
|
SYM *sym;
|
SYM *sym;
|
int64_t ca;
|
int64_t ca;
|
int div = 1;
|
int div = 1;
|
|
|
if (gCpu==7)
|
if (gCpu==7)
|
div = 2;
|
div = 2;
|
|
|
NextToken();
|
NextToken();
|
if (token==tk_code) {
|
if (token==tk_code) {
|
segment = codeseg;
|
segment = codeseg;
|
}
|
}
|
else if (token==tk_rodata) {
|
else if (token==tk_rodata) {
|
segment = rodataseg;
|
segment = rodataseg;
|
}
|
}
|
else if (token==tk_data) {
|
else if (token==tk_data) {
|
if (isInitializationData)
|
if (isInitializationData)
|
segment = rodataseg;
|
segment = rodataseg;
|
else
|
else
|
segment = dataseg;
|
segment = dataseg;
|
}
|
}
|
else if (token==tk_bss) {
|
else if (token==tk_bss) {
|
segment = bssseg;
|
segment = bssseg;
|
}
|
}
|
else
|
else
|
prevToken();
|
prevToken();
|
bump_address();
|
bump_address();
|
// if (segment==bssseg)
|
// if (segment==bssseg)
|
// ca = bss_address;
|
// ca = bss_address;
|
// else
|
// else
|
// ca = code_address;
|
// ca = code_address;
|
switch(segment) {
|
switch(segment) {
|
case codeseg:
|
case codeseg:
|
ca = code_address/div;
|
ca = code_address/div;
|
ca = sections[0].address/div;
|
ca = sections[0].address/div;
|
break;
|
break;
|
case rodataseg:
|
case rodataseg:
|
ca = sections[1].address/div;
|
ca = sections[1].address/div;
|
break;
|
break;
|
case dataseg:
|
case dataseg:
|
ca = sections[2].address/div;
|
ca = sections[2].address/div;
|
break;
|
break;
|
case bssseg:
|
case bssseg:
|
ca = sections[3].address/div;
|
ca = sections[3].address/div;
|
break;
|
break;
|
case tlsseg:
|
case tlsseg:
|
ca = sections[4].address/div;
|
ca = sections[4].address/div;
|
break;
|
break;
|
}
|
}
|
NextToken();
|
NextToken();
|
if (token != tk_id) {
|
if (token != tk_id) {
|
printf("Identifier expected. Token %d\r\n", token);
|
printf("Identifier expected. Token %d\r\n", token);
|
printf("Line:%.60s", stptr);
|
printf("Line:%.60s", stptr);
|
}
|
}
|
else {
|
else {
|
if (isInitializationData) {
|
if (isInitializationData) {
|
ScanToEOL();
|
ScanToEOL();
|
inptr++;
|
inptr++;
|
return;
|
return;
|
}
|
}
|
sym = find_symbol(lastid);
|
sym = find_symbol(lastid);
|
if (pass == 4) {
|
if (pass == 4) {
|
if (sym) {
|
if (sym) {
|
if (sym->defined)
|
if (sym->defined)
|
printf("Symbol (%s) already defined.\r\n", lastid);
|
printf("Symbol (%s) already defined.\r\n", lastid);
|
}
|
}
|
else {
|
else {
|
sym = new_symbol(lastid);
|
sym = new_symbol(lastid);
|
}
|
}
|
if (sym) {
|
if (sym) {
|
sym->defined = 1;
|
sym->defined = 1;
|
if (gCpu=='G')
|
if (gCpu=='G')
|
sym->value.low = ca & -4LL;
|
sym->value.low = ca & -4LL;
|
else
|
else
|
sym->value.low = ca;
|
sym->value.low = ca;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
sym->segment = segment;
|
sym->segment = segment;
|
sym->scope = 'P';
|
sym->scope = 'P';
|
}
|
}
|
}
|
}
|
else if (pass > 4) {
|
else if (pass > 4) {
|
if (!sym)
|
if (!sym)
|
printf("Symbol (%s) not defined.\r\n", lastid);
|
printf("Symbol (%s) not defined.\r\n", lastid);
|
else {
|
else {
|
if (sym->value.low != ca) {
|
if (sym->value.low != ca) {
|
phasing_errors++;
|
phasing_errors++;
|
sym->phaserr = '*';
|
sym->phaserr = '*';
|
//if (bGen) printf("%s=%06I64x ca=%06I64x\r\n", nmTable.GetName(sym->name), sym->value, code_address);
|
//if (bGen) printf("%s=%06I64x ca=%06I64x\r\n", nmTable.GetName(sym->name), sym->value, code_address);
|
}
|
}
|
else
|
else
|
sym->phaserr = ' ';
|
sym->phaserr = ' ';
|
if (gCpu=='G')
|
if (gCpu=='G')
|
sym->value.low = ca & -4LL;
|
sym->value.low = ca & -4LL;
|
else
|
else
|
sym->value.low = ca;
|
sym->value.low = ca;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
}
|
}
|
}
|
}
|
strcpy_s(current_label, sizeof(current_label), lastid);
|
strcpy_s(current_label, sizeof(current_label), lastid);
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
inptr++;
|
inptr++;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// extern somefn
|
// extern somefn
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_extern()
|
void process_extern()
|
{
|
{
|
SYM *sym;
|
SYM *sym;
|
|
|
// printf("<process_extern>");
|
// printf("<process_extern>");
|
NextToken();
|
NextToken();
|
if (token != tk_id)
|
if (token != tk_id)
|
printf("Expecting an identifier.\r\n");
|
printf("Expecting an identifier.\r\n");
|
else {
|
else {
|
sym = find_symbol(lastid);
|
sym = find_symbol(lastid);
|
if (pass == 4) {
|
if (pass == 4) {
|
if (sym) {
|
if (sym) {
|
|
|
}
|
}
|
else {
|
else {
|
sym = new_symbol(lastid);
|
sym = new_symbol(lastid);
|
}
|
}
|
if (sym) {
|
if (sym) {
|
sym->defined = 0;
|
sym->defined = 0;
|
sym->value.low = 0;
|
sym->value.low = 0;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
sym->segment = segment;
|
sym->segment = segment;
|
sym->scope = 'P';
|
sym->scope = 'P';
|
sym->isExtern = 1;
|
sym->isExtern = 1;
|
}
|
}
|
}
|
}
|
else if (pass > 4) {
|
else if (pass > 4) {
|
}
|
}
|
NextToken();
|
NextToken();
|
if (token==':') {
|
if (token==':') {
|
NextToken();
|
NextToken();
|
if (sym)
|
if (sym)
|
sym->bits = (int)expr();
|
sym->bits = (int)expr();
|
}
|
}
|
else {
|
else {
|
// printf("J:sym=%p lastid=%s", sym, lastid);
|
// printf("J:sym=%p lastid=%s", sym, lastid);
|
prevToken();
|
prevToken();
|
if (sym)
|
if (sym)
|
sym->bits = 32;
|
sym->bits = 32;
|
}
|
}
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
inptr++;
|
inptr++;
|
// printf("</process_extern>\r\n");
|
// printf("</process_extern>\r\n");
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// .org $23E200
|
// .org $23E200
|
// .org is ignored for relocatable files.
|
// .org is ignored for relocatable files.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_org()
|
void process_org()
|
{
|
{
|
int64_t new_address;
|
int64_t new_address;
|
int mul = 1;
|
int mul = 1;
|
|
|
if (gCpu==7)
|
if (gCpu==7)
|
mul = 2;
|
mul = 2;
|
NextToken();
|
NextToken();
|
new_address = expr();
|
new_address = expr();
|
if (!rel_out) {
|
if (!rel_out) {
|
if (segment==dataseg) {
|
if (segment==dataseg) {
|
data_address = new_address*mul;
|
data_address = new_address*mul;
|
sections[segment].address = new_address*mul;
|
sections[segment].address = new_address*mul;
|
}
|
}
|
else if (segment==bssseg || segment==tlsseg) {
|
else if (segment==bssseg || segment==tlsseg) {
|
bss_address = new_address*mul;
|
bss_address = new_address*mul;
|
sections[segment].address = new_address*mul;
|
sections[segment].address = new_address*mul;
|
}
|
}
|
else {
|
else {
|
if (first_org && segment==codeseg) {
|
if (first_org && segment==codeseg) {
|
program_address = new_address;
|
program_address = new_address;
|
code_address = new_address;
|
code_address = new_address;
|
start_address = new_address*mul;
|
start_address = new_address*mul;
|
sections[0].address = new_address*mul;
|
sections[0].address = new_address*mul;
|
first_org = 0;
|
first_org = 0;
|
}
|
}
|
else {
|
else {
|
// Ignore the org directive in initialized data area of rodata
|
// Ignore the org directive in initialized data area of rodata
|
if (!isInitializationData)
|
if (!isInitializationData)
|
while(sections[0].address < new_address*mul)
|
while(sections[0].address < new_address*mul)
|
emitByte(0x00);
|
emitByte(0x00);
|
}
|
}
|
}
|
}
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_align()
|
void process_align()
|
{
|
{
|
int64_t v;
|
int64_t v;
|
|
|
NextToken();
|
NextToken();
|
if (token == tk_code && gCpu=='F')
|
if (token == tk_code && gCpu=='F')
|
v = 5;
|
v = 5;
|
else
|
else
|
v = expr();
|
v = expr();
|
if (v == 0) {
|
if (v == 0) {
|
printf("Bad align directive. (%d)\r\n", lineno);
|
printf("Bad align directive. (%d)\r\n", lineno);
|
return;
|
return;
|
}
|
}
|
if (segment == codeseg || segment == rodataseg || segment == dataseg || segment==bssseg || segment==tlsseg) {
|
if (segment == codeseg || segment == rodataseg || segment == dataseg || segment==bssseg || segment==tlsseg) {
|
while (sections[segment].address % v)
|
while (sections[segment].address % v)
|
emitByte(0x00);
|
emitByte(0x00);
|
}
|
}
|
// if (segment==bssseg) {
|
// if (segment==bssseg) {
|
// while (bss_address % v)
|
// while (bss_address % v)
|
// emitByte(0x00);
|
// emitByte(0x00);
|
// }
|
// }
|
// else {
|
// else {
|
// while (code_address % v)
|
// while (code_address % v)
|
// emitByte(0x00);
|
// emitByte(0x00);
|
// }
|
// }
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// hint #1
|
// hint #1
|
//
|
//
|
// Process a compiler hint. Normally these instructions don't make it through
|
// Process a compiler hint. Normally these instructions don't make it through
|
// the compile stage, but in case one does... It is just ignored.
|
// the compile stage, but in case one does... It is just ignored.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_hint()
|
void process_hint()
|
{
|
{
|
int64_t v;
|
int64_t v;
|
|
|
NextToken();
|
NextToken();
|
v = expr();
|
v = expr();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// code 0x8000 to 0xFFFF
|
// code 0x8000 to 0xFFFF
|
// code 24 bits
|
// code 24 bits
|
// code
|
// code
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_code()
|
void process_code()
|
{
|
{
|
int64_t st, nd;
|
int64_t st, nd;
|
|
|
segment = codeseg;
|
segment = codeseg;
|
NextToken();
|
NextToken();
|
if (token==tk_eol) {
|
if (token==tk_eol) {
|
prevToken();
|
prevToken();
|
return;
|
return;
|
}
|
}
|
st = expr();
|
st = expr();
|
if (token==tk_bits) {
|
if (token==tk_bits) {
|
code_bits = (int)st;
|
code_bits = (int)st;
|
return;
|
return;
|
}
|
}
|
if (token==tk_to) {
|
if (token==tk_to) {
|
NextToken();
|
NextToken();
|
nd = expr();
|
nd = expr();
|
code_bits = (int)log((double)nd+1)/log(2.0); // +1 to round up a little bit
|
code_bits = (int)log((double)nd+1)/log(2.0); // +1 to round up a little bit
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// data 0x8000 to 0xFFFF
|
// data 0x8000 to 0xFFFF
|
// data 24 bits
|
// data 24 bits
|
// data
|
// data
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_data(int seg)
|
void process_data(int seg)
|
{
|
{
|
int64_t st, nd;
|
int64_t st, nd;
|
|
|
segment = seg;
|
segment = seg;
|
NextToken();
|
NextToken();
|
if (token==tk_eol) {
|
if (token==tk_eol) {
|
prevToken();
|
prevToken();
|
return;
|
return;
|
}
|
}
|
st = expr();
|
st = expr();
|
if (token==tk_bits) {
|
if (token==tk_bits) {
|
data_bits = (int)st;
|
data_bits = (int)st;
|
return;
|
return;
|
}
|
}
|
if (token==tk_to) {
|
if (token==tk_to) {
|
NextToken();
|
NextToken();
|
nd = expr();
|
nd = expr();
|
data_bits = (int)log((double)nd+1)/log((double)2.0); // +1 to round up a little bit
|
data_bits = (int)log((double)nd+1)/log((double)2.0); // +1 to round up a little bit
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_db()
|
void process_db()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
SkipSpaces();
|
SkipSpaces();
|
//NextToken();
|
//NextToken();
|
while(token!=tk_eol) {
|
while(token!=tk_eol) {
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr=='\n') break;
|
if (*inptr=='\n') break;
|
if (*inptr=='"') {
|
if (*inptr=='"') {
|
inptr++;
|
inptr++;
|
while (*inptr!='"') {
|
while (*inptr!='"') {
|
if (*inptr=='\\') {
|
if (*inptr=='\\') {
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case '\\': emitByte('\\'); inptr++; break;
|
case '\\': emitByte('\\'); inptr++; break;
|
case 'r': emitByte(0x0D); inptr++; break;
|
case 'r': emitByte(0x0D); inptr++; break;
|
case 'n': emitByte(0x0A); inptr++; break;
|
case 'n': emitByte(0x0A); inptr++; break;
|
case 'b': emitByte('\b'); inptr++; break;
|
case 'b': emitByte('\b'); inptr++; break;
|
case '"': emitByte('"'); inptr++; break;
|
case '"': emitByte('"'); inptr++; break;
|
default: inptr++; break;
|
default: inptr++; break;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
emitByte(*inptr);
|
emitByte(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
inptr++;
|
inptr++;
|
}
|
}
|
/*
|
/*
|
else if (*inptr=='\'') {
|
else if (*inptr=='\'') {
|
inptr++;
|
inptr++;
|
emitByte(*inptr);
|
emitByte(*inptr);
|
inptr++;
|
inptr++;
|
if (*inptr!='\'') {
|
if (*inptr!='\'') {
|
printf("Missing ' in character constant.\r\n");
|
printf("Missing ' in character constant.\r\n");
|
}
|
}
|
}
|
}
|
*/
|
*/
|
else {
|
else {
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
emitByte(val & 255);
|
emitByte(val & 255);
|
prevToken();
|
prevToken();
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr!=',')
|
if (*inptr!=',')
|
break;
|
break;
|
inptr++;
|
inptr++;
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_dc()
|
void process_dc()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
SkipSpaces();
|
SkipSpaces();
|
while(token!=tk_eol) {
|
while(token!=tk_eol) {
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr=='"') {
|
if (*inptr=='"') {
|
inptr++;
|
inptr++;
|
while (*inptr!='"') {
|
while (*inptr!='"') {
|
if (*inptr=='\\') {
|
if (*inptr=='\\') {
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case '\\': emitChar('\\'); inptr++; break;
|
case '\\': emitChar('\\'); inptr++; break;
|
case 'r': emitChar(0x0D); inptr++; break;
|
case 'r': emitChar(0x0D); inptr++; break;
|
case 'n': emitChar(0x0A); inptr++; break;
|
case 'n': emitChar(0x0A); inptr++; break;
|
case 'b': emitChar('\b'); inptr++; break;
|
case 'b': emitChar('\b'); inptr++; break;
|
case '"': emitChar('"'); inptr++; break;
|
case '"': emitChar('"'); inptr++; break;
|
default: inptr++; break;
|
default: inptr++; break;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
emitChar(*inptr);
|
emitChar(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
inptr++;
|
inptr++;
|
}
|
}
|
else if (*inptr=='\'') {
|
else if (*inptr=='\'') {
|
inptr++;
|
inptr++;
|
emitChar(*inptr);
|
emitChar(*inptr);
|
inptr++;
|
inptr++;
|
if (*inptr!='\'') {
|
if (*inptr!='\'') {
|
printf("Missing ' in character constant.\r\n");
|
printf("Missing ' in character constant.\r\n");
|
}
|
}
|
}
|
}
|
else {
|
else {
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
emitChar(val);
|
emitChar(val);
|
prevToken();
|
prevToken();
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr!=',')
|
if (*inptr!=',')
|
break;
|
break;
|
inptr++;
|
inptr++;
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_dh()
|
void process_dh()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
SkipSpaces();
|
SkipSpaces();
|
while(token!=tk_eol) {
|
while(token!=tk_eol) {
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr=='"') {
|
if (*inptr=='"') {
|
inptr++;
|
inptr++;
|
while (*inptr!='"') {
|
while (*inptr!='"') {
|
if (*inptr=='\\') {
|
if (*inptr=='\\') {
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case '\\': emitHalf('\\'); inptr++; break;
|
case '\\': emitHalf('\\'); inptr++; break;
|
case 'r': emitHalf(0x0D); inptr++; break;
|
case 'r': emitHalf(0x0D); inptr++; break;
|
case 'n': emitHalf(0x0A); inptr++; break;
|
case 'n': emitHalf(0x0A); inptr++; break;
|
case 'b': emitHalf('\b'); inptr++; break;
|
case 'b': emitHalf('\b'); inptr++; break;
|
case '"': emitHalf('"'); inptr++; break;
|
case '"': emitHalf('"'); inptr++; break;
|
default: inptr++; break;
|
default: inptr++; break;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
emitHalf(*inptr);
|
emitHalf(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
inptr++;
|
inptr++;
|
}
|
}
|
else if (*inptr=='\'') {
|
else if (*inptr=='\'') {
|
inptr++;
|
inptr++;
|
emitHalf(*inptr);
|
emitHalf(*inptr);
|
inptr++;
|
inptr++;
|
if (*inptr!='\'') {
|
if (*inptr!='\'') {
|
printf("Missing ' in character constant.\r\n");
|
printf("Missing ' in character constant.\r\n");
|
}
|
}
|
}
|
}
|
else {
|
else {
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
emitHalf(val);
|
emitHalf(val);
|
prevToken();
|
prevToken();
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr!=',')
|
if (*inptr!=',')
|
break;
|
break;
|
inptr++;
|
inptr++;
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_dh_htbl()
|
void process_dh_htbl()
|
{
|
{
|
int nn;
|
int nn;
|
|
|
if (gCpu=='F') {
|
if (gCpu=='F') {
|
emitWord(htblmax > 1024 ? 1024 : htblmax);
|
emitWord(htblmax > 1024 ? 1024 : htblmax);
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
emitWord(hTable[nn].opcode);
|
emitWord(hTable[nn].opcode);
|
}
|
}
|
return;
|
return;
|
}
|
}
|
else if (gCpu==7)
|
else if (gCpu==7)
|
emitByte(htblmax > 1024 ? 1024 : htblmax);
|
emitByte(htblmax > 1024 ? 1024 : htblmax);
|
else
|
else
|
emitHalf(htblmax > 1024 ? 1024 : htblmax);
|
emitHalf(htblmax > 1024 ? 1024 : htblmax);
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
for (nn = 0; nn < htblmax && nn < 1024; nn++) {
|
emitWord(hTable[nn].opcode);
|
emitWord(hTable[nn].opcode);
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_dw()
|
void process_dw()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
SkipSpaces();
|
SkipSpaces();
|
while(token!=tk_eol) {
|
while(token!=tk_eol) {
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr=='"') {
|
if (*inptr=='"') {
|
inptr++;
|
inptr++;
|
while (*inptr!='"') {
|
while (*inptr!='"') {
|
if (*inptr=='\\') {
|
if (*inptr=='\\') {
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case '\\': emitWord('\\'); inptr++; break;
|
case '\\': emitWord('\\'); inptr++; break;
|
case 'r': emitWord(0x0D); inptr++; break;
|
case 'r': emitWord(0x0D); inptr++; break;
|
case 'n': emitWord(0x0A); inptr++; break;
|
case 'n': emitWord(0x0A); inptr++; break;
|
case 'b': emitWord('\b'); inptr++; break;
|
case 'b': emitWord('\b'); inptr++; break;
|
case '"': emitWord('"'); inptr++; break;
|
case '"': emitWord('"'); inptr++; break;
|
default: inptr++; break;
|
default: inptr++; break;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
emitWord(*inptr);
|
emitWord(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
inptr++;
|
inptr++;
|
}
|
}
|
else if (*inptr=='\'') {
|
else if (*inptr=='\'') {
|
inptr++;
|
inptr++;
|
emitWord(*inptr);
|
emitWord(*inptr);
|
inptr++;
|
inptr++;
|
if (*inptr!='\'') {
|
if (*inptr!='\'') {
|
printf("Missing ' in character constant.\r\n");
|
printf("Missing ' in character constant.\r\n");
|
}
|
}
|
}
|
}
|
else {
|
else {
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
// A pointer to an object might be emitted as a data word.
|
// A pointer to an object might be emitted as a data word.
|
if (bGen && lastsym)
|
if (bGen && lastsym)
|
if( lastsym->segment < 5)
|
if( lastsym->segment < 5)
|
sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
|
sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
|
emitWord(val);
|
emitWord(val);
|
prevToken();
|
prevToken();
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr!=',')
|
if (*inptr!=',')
|
break;
|
break;
|
inptr++;
|
inptr++;
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_dd()
|
void process_dd()
|
{
|
{
|
Int128 val;
|
Int128 val;
|
|
|
SkipSpaces();
|
SkipSpaces();
|
while(token!=tk_eol) {
|
while(token!=tk_eol) {
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr=='"') {
|
if (*inptr=='"') {
|
inptr++;
|
inptr++;
|
while (*inptr!='"') {
|
while (*inptr!='"') {
|
if (*inptr=='\\') {
|
if (*inptr=='\\') {
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case '\\': emitWord('\\'); emitChar(0); inptr++; break;
|
case '\\': emitWord('\\'); emitChar(0); inptr++; break;
|
case 'r': emitWord(0x0D); emitChar(0); inptr++; break;
|
case 'r': emitWord(0x0D); emitChar(0); inptr++; break;
|
case 'n': emitWord(0x0A); emitChar(0); inptr++; break;
|
case 'n': emitWord(0x0A); emitChar(0); inptr++; break;
|
case 'b': emitWord('\b'); emitChar(0); inptr++; break;
|
case 'b': emitWord('\b'); emitChar(0); inptr++; break;
|
case '"': emitWord('"'); emitChar(0); inptr++; break;
|
case '"': emitWord('"'); emitChar(0); inptr++; break;
|
default: inptr++; break;
|
default: inptr++; break;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
emitWord(*inptr);
|
emitWord(*inptr);
|
emitChar(0);
|
emitChar(0);
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
inptr++;
|
inptr++;
|
}
|
}
|
else if (*inptr=='\'') {
|
else if (*inptr=='\'') {
|
inptr++;
|
inptr++;
|
emitWord(*inptr);
|
emitWord(*inptr);
|
emitChar(0);
|
emitChar(0);
|
inptr++;
|
inptr++;
|
if (*inptr!='\'') {
|
if (*inptr!='\'') {
|
printf("Missing ' in character constant.\r\n");
|
printf("Missing ' in character constant.\r\n");
|
}
|
}
|
}
|
}
|
else {
|
else {
|
NextToken();
|
NextToken();
|
val = expr128();
|
val = expr128();
|
// A pointer to an object might be emitted as a data word.
|
// A pointer to an object might be emitted as a data word.
|
if (bGen && lastsym)
|
if (bGen && lastsym)
|
if( lastsym->segment < 5)
|
if( lastsym->segment < 5)
|
sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
|
sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
|
emitDecibyte(val);
|
emitDecibyte(val);
|
prevToken();
|
prevToken();
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr!=',')
|
if (*inptr!=',')
|
break;
|
break;
|
inptr++;
|
inptr++;
|
}
|
}
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// fill.b 252,0x00
|
// fill.b 252,0x00
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_fill()
|
void process_fill()
|
{
|
{
|
char sz = 'b';
|
char sz = 'b';
|
int64_t count;
|
int64_t count;
|
int64_t val;
|
int64_t val;
|
int64_t nn;
|
int64_t nn;
|
|
|
if (*inptr=='.') {
|
if (*inptr=='.') {
|
inptr++;
|
inptr++;
|
if (strchr("bchwBCHW",*inptr)) {
|
if (strchr("bchwBCHW",*inptr)) {
|
sz = tolower(*inptr);
|
sz = tolower(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
else
|
else
|
printf("Illegal fill size.\r\n");
|
printf("Illegal fill size.\r\n");
|
}
|
}
|
SkipSpaces();
|
SkipSpaces();
|
NextToken();
|
NextToken();
|
count = expr();
|
count = expr();
|
prevToken();
|
prevToken();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
prevToken();
|
prevToken();
|
for (nn = 0; nn < count; nn++)
|
for (nn = 0; nn < count; nn++)
|
switch(sz) {
|
switch(sz) {
|
case 'b': emitByte(val); break;
|
case 'b': emitByte(val); break;
|
case 'c': emitChar(val); break;
|
case 'c': emitChar(val); break;
|
case 'h': emitHalf(val); break;
|
case 'h': emitHalf(val); break;
|
case 'w': emitWord(val); break;
|
case 'w': emitWord(val); break;
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Bump up the address to the next aligned code address.
|
// Bump up the address to the next aligned code address.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void bump_address()
|
void bump_address()
|
{
|
{
|
if (gCpu==888 || gCpu==889)
|
if (gCpu==888 || gCpu==889)
|
Table888_bump_address();
|
Table888_bump_address();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// macro <name> (<arg1, arg2, arg3, ...>)
|
// macro <name> (<arg1, arg2, arg3, ...>)
|
// < macro body >
|
// < macro body >
|
// endm
|
// endm
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
void process_macro()
|
void process_macro()
|
{
|
{
|
SYM *sym;
|
SYM *sym;
|
Macro *macr;
|
Macro *macr;
|
bool alreadyDef = false;
|
bool alreadyDef = false;
|
char *p;
|
char *p;
|
|
|
if (pass == 3) {
|
if (pass == 3) {
|
macr = new Macro;
|
macr = new Macro;
|
SkipSpaces();
|
SkipSpaces();
|
getIdentifier();
|
getIdentifier();
|
sym = find_symbol(lastid);
|
sym = find_symbol(lastid);
|
if (sym != nullptr) {
|
if (sym != nullptr) {
|
printf("Macro already defined %d.", lineno);
|
printf("Macro already defined %d.", lineno);
|
alreadyDef = true;
|
alreadyDef = true;
|
}
|
}
|
else {
|
else {
|
sym = new_symbol(lastid);
|
sym = new_symbol(lastid);
|
sym->defined = 1;
|
sym->defined = 1;
|
sym->isMacro = true;
|
sym->isMacro = true;
|
sym->macro = macr;
|
sym->macro = macr;
|
}
|
}
|
NextToken();
|
NextToken();
|
if (token == '(') {
|
if (token == '(') {
|
macr->GetParmList();
|
macr->GetParmList();
|
NextToken();
|
NextToken();
|
need(')');
|
need(')');
|
}
|
}
|
p = inptr;
|
p = inptr;
|
macr->GetBody();
|
macr->GetBody();
|
if (alreadyDef)
|
if (alreadyDef)
|
delete macr;
|
delete macr;
|
}
|
}
|
else if (pass > 3) {
|
else if (pass > 3) {
|
Macro mthrowaway;
|
Macro mthrowaway;
|
SkipSpaces();
|
SkipSpaces();
|
getIdentifier();
|
getIdentifier();
|
NextToken();
|
NextToken();
|
if (token == '(') {
|
if (token == '(') {
|
mthrowaway.GetParmList();
|
mthrowaway.GetParmList();
|
NextToken();
|
NextToken();
|
need(')');
|
need(')');
|
}
|
}
|
mthrowaway.GetBody();
|
mthrowaway.GetBody();
|
}
|
}
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
void process_message()
|
void process_message()
|
{
|
{
|
char buf[200];
|
char buf[200];
|
int nn;
|
int nn;
|
|
|
while(*inptr != '"' && *inptr != '\n') inptr++;
|
while(*inptr != '"' && *inptr != '\n') inptr++;
|
if (*inptr=='\n') { NextToken(); return; }
|
if (*inptr=='\n') { NextToken(); return; }
|
nn = 0;
|
nn = 0;
|
inptr++;
|
inptr++;
|
while (*inptr != '"' && *inptr != '\n' && nn < 197) {
|
while (*inptr != '"' && *inptr != '\n' && nn < 197) {
|
buf[nn] = *inptr;
|
buf[nn] = *inptr;
|
inptr++;
|
inptr++;
|
nn++;
|
nn++;
|
}
|
}
|
buf[nn] = '\0';
|
buf[nn] = '\0';
|
strcat_s(buf, sizeof(buf), "\r\n");
|
strcat_s(buf, sizeof(buf), "\r\n");
|
printf(buf);
|
printf(buf);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// label:
|
// label:
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void process_label()
|
void process_label()
|
{
|
{
|
SYM *sym;
|
SYM *sym;
|
static char nm[500];
|
static char nm[500];
|
int64_t ca;
|
int64_t ca;
|
Int128 val;
|
Int128 val;
|
int isEquate;
|
int isEquate;
|
int shft = 0;
|
int shft = 0;
|
|
|
val.low = 0;
|
val.low = 0;
|
val.high = 0;
|
val.high = 0;
|
if (gCpu==7)
|
if (gCpu==7)
|
shft = 1;
|
shft = 1;
|
|
|
// printf("<process_label>");
|
// printf("<process_label>");
|
isEquate = 0;
|
isEquate = 0;
|
// Bump up the address to align it with a valid code address if needed.
|
// Bump up the address to align it with a valid code address if needed.
|
bump_address();
|
bump_address();
|
switch(segment) {
|
switch(segment) {
|
case codeseg:
|
case codeseg:
|
ca = code_address >> shft;
|
ca = code_address >> shft;
|
ca = sections[0].address >> shft;
|
ca = sections[0].address >> shft;
|
break;
|
break;
|
case rodataseg:
|
case rodataseg:
|
ca = sections[1].address >> shft;
|
ca = sections[1].address >> shft;
|
break;
|
break;
|
case dataseg:
|
case dataseg:
|
ca = sections[2].address >> shft;
|
ca = sections[2].address >> shft;
|
break;
|
break;
|
case bssseg:
|
case bssseg:
|
ca = sections[3].address >> shft;
|
ca = sections[3].address >> shft;
|
break;
|
break;
|
case tlsseg:
|
case tlsseg:
|
ca = sections[4].address >> shft;
|
ca = sections[4].address >> shft;
|
break;
|
break;
|
default:
|
default:
|
ca = code_address >> shft;
|
ca = code_address >> shft;
|
ca = sections[0].address >> shft;
|
ca = sections[0].address >> shft;
|
break;
|
break;
|
}
|
}
|
// if (segment==bssseg)
|
// if (segment==bssseg)
|
// ca = bss_address;
|
// ca = bss_address;
|
// else
|
// else
|
// ca = code_address;
|
// ca = code_address;
|
if (lastid[0]=='.') {
|
if (lastid[0]=='.') {
|
sprintf_s(nm, sizeof(nm), "%s%s", current_label, lastid);
|
sprintf_s(nm, sizeof(nm), "%s%s", current_label, lastid);
|
}
|
}
|
else {
|
else {
|
strcpy_s(current_label, sizeof(current_label), lastid);
|
strcpy_s(current_label, sizeof(current_label), lastid);
|
strcpy_s(nm, sizeof(nm), lastid);
|
strcpy_s(nm, sizeof(nm), lastid);
|
}
|
}
|
if (strcmp("end_init_data", nm)==0)
|
if (strcmp("end_init_data", nm)==0)
|
isInitializationData = 0;
|
isInitializationData = 0;
|
NextToken();
|
NextToken();
|
// SkipSpaces();
|
// SkipSpaces();
|
if (token==tk_equ || token==tk_eq) {
|
if (token==tk_equ || token==tk_eq) {
|
NextToken();
|
NextToken();
|
val = expr128();
|
val = expr128();
|
isEquate = 1;
|
isEquate = 1;
|
}
|
}
|
else {
|
else {
|
prevToken();
|
prevToken();
|
val.low = ca;
|
val.low = ca;
|
val.high = 0;
|
val.high = 0;
|
}
|
}
|
// if (token==tk_eol)
|
// if (token==tk_eol)
|
// prevToken();
|
// prevToken();
|
//else if (token==':') inptr++;
|
//else if (token==':') inptr++;
|
// ignore the labels in initialization data
|
// ignore the labels in initialization data
|
if (isInitializationData)
|
if (isInitializationData)
|
return;
|
return;
|
sym = find_symbol(nm);
|
sym = find_symbol(nm);
|
if (pass==4 || pass==3) {
|
if (pass==4 || pass==3) {
|
if (sym) {
|
if (sym) {
|
if (sym->defined) {
|
if (sym->defined) {
|
//if (!Int128::IsEqual(&sym->value, &val)) {
|
//if (!Int128::IsEqual(&sym->value, &val)) {
|
// printf("Label %s already defined %ld vs %ld.\r\n", nm, sym->value.low, val.low);
|
// printf("Label %s already defined %ld vs %ld.\r\n", nm, sym->value.low, val.low);
|
// printf("Line %d: %.60s\r\n", lineno, stptr);
|
// printf("Line %d: %.60s\r\n", lineno, stptr);
|
//}
|
//}
|
}
|
}
|
sym->defined = 1;
|
sym->defined = 1;
|
if (isEquate) {
|
if (isEquate) {
|
sym->value = val;
|
sym->value = val;
|
sym->segment = constseg;
|
sym->segment = constseg;
|
sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
|
sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
|
}
|
}
|
else {
|
else {
|
if (gCpu=='G')
|
if (gCpu=='G')
|
sym->value.low = ca & -4LL;
|
sym->value.low = ca & -4LL;
|
else
|
else
|
sym->value.low = ca;
|
sym->value.low = ca;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
sym->segment = segment;
|
sym->segment = segment;
|
if (segment==codeseg)
|
if (segment==codeseg)
|
sym->bits = code_bits;
|
sym->bits = code_bits;
|
else
|
else
|
sym->bits = data_bits;
|
sym->bits = data_bits;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
sym = new_symbol(nm);
|
sym = new_symbol(nm);
|
sym->defined = 1;
|
sym->defined = 1;
|
if (isEquate) {
|
if (isEquate) {
|
sym->value = val;
|
sym->value = val;
|
sym->segment = constseg;
|
sym->segment = constseg;
|
sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
|
sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
|
}
|
}
|
else {
|
else {
|
if (gCpu=='G')
|
if (gCpu=='G')
|
sym->value.low = ca & -4LL;
|
sym->value.low = ca & -4LL;
|
else
|
else
|
sym->value.low = ca;
|
sym->value.low = ca;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
sym->segment = segment;
|
sym->segment = segment;
|
if (segment==codeseg)
|
if (segment==codeseg)
|
sym->bits = code_bits;
|
sym->bits = code_bits;
|
else
|
else
|
sym->bits = data_bits;
|
sym->bits = data_bits;
|
}
|
}
|
}
|
}
|
}
|
}
|
else if (pass>4) {
|
else if (pass>4) {
|
if (!sym) {
|
if (!sym) {
|
printf("Internal error: SYM is NULL.\r\n");
|
printf("Internal error: SYM is NULL.\r\n");
|
printf("Couldn't find <%s>\r\n", nm);
|
printf("Couldn't find <%s>\r\n", nm);
|
}
|
}
|
else {
|
else {
|
if (isEquate) {
|
if (isEquate) {
|
sym->value = val;
|
sym->value = val;
|
}
|
}
|
else {
|
else {
|
if ((sym->value.low != ca && gCpu!='G') || (sym->value.low != (ca & -4LL) && gCpu=='G')) {
|
if ((sym->value.low != ca && gCpu!='G') || (sym->value.low != (ca & -4LL) && gCpu=='G')) {
|
phasing_errors++;
|
phasing_errors++;
|
sym->phaserr = '*';
|
sym->phaserr = '*';
|
//if (bGen) printf("%s=%06llx ca=%06llx\r\n", nmTable.GetName(sym->name), sym->value, code_address);
|
//if (bGen) printf("%s=%06llx ca=%06llx\r\n", nmTable.GetName(sym->name), sym->value, code_address);
|
}
|
}
|
else
|
else
|
sym->phaserr = ' ';
|
sym->phaserr = ' ';
|
if (gCpu=='G')
|
if (gCpu=='G')
|
sym->value.low = ca & -4LL;
|
sym->value.low = ca & -4LL;
|
else
|
else
|
sym->value.low = ca;
|
sym->value.low = ca;
|
sym->value.high = 0;
|
sym->value.high = 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (strcmp("begin_init_data", nm)==0)
|
if (strcmp("begin_init_data", nm)==0)
|
isInitializationData = 1;
|
isInitializationData = 1;
|
// printf("</process_ label>\r\n");
|
// printf("</process_ label>\r\n");
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Group and reorder the segments in the master file.
|
// Group and reorder the segments in the master file.
|
// code placed first
|
// code placed first
|
// rodata followed by
|
// rodata followed by
|
// data
|
// data
|
// tls
|
// tls
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void processSegments()
|
void processSegments()
|
{
|
{
|
char *pinptr;
|
char *pinptr;
|
int segment = codeseg;
|
int segment = codeseg;
|
int inComment;
|
int inComment;
|
std::string fname;
|
std::string fname;
|
bool setname = false;
|
bool setname = false;
|
|
|
if (verbose)
|
if (verbose)
|
printf("Processing segments.\r\n");
|
printf("Processing segments.\r\n");
|
inptr = &masterFile[0];
|
inptr = &masterFile[0];
|
pinptr = inptr;
|
pinptr = inptr;
|
codendx = 0;
|
codendx = 0;
|
datandx = 0;
|
datandx = 0;
|
rodatandx = 0;
|
rodatandx = 0;
|
tlsndx = 0;
|
tlsndx = 0;
|
bssndx = 0;
|
bssndx = 0;
|
ZeroMemory(codebuf,sizeof(codebuf));
|
ZeroMemory(codebuf,sizeof(codebuf));
|
ZeroMemory(databuf,sizeof(databuf));
|
ZeroMemory(databuf,sizeof(databuf));
|
ZeroMemory(rodatabuf,sizeof(rodatabuf));
|
ZeroMemory(rodatabuf,sizeof(rodatabuf));
|
ZeroMemory(tlsbuf,sizeof(tlsbuf));
|
ZeroMemory(tlsbuf,sizeof(tlsbuf));
|
ZeroMemory(bssbuf,sizeof(bssbuf));
|
ZeroMemory(bssbuf,sizeof(bssbuf));
|
inComment = 0;
|
inComment = 0;
|
|
|
lineno = 1;
|
lineno = 1;
|
while (*inptr) {
|
while (*inptr) {
|
if (*inptr == '\n')
|
if (*inptr == '\n')
|
lineno++;
|
lineno++;
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr == ';')
|
if (*inptr == ';')
|
goto j1;
|
goto j1;
|
if (inptr[0] == '/' && inptr[1] == '/')
|
if (inptr[0] == '/' && inptr[1] == '/')
|
goto j1;
|
goto j1;
|
// if (inptr[0]=='/' && inptr[1]=='*') {
|
// if (inptr[0]=='/' && inptr[1]=='*') {
|
// inComment = 1;
|
// inComment = 1;
|
// goto j1;
|
// goto j1;
|
// }
|
// }
|
// if (inComment && inptr[0]=='*' && inptr[1]=='/')
|
// if (inComment && inptr[0]=='*' && inptr[1]=='/')
|
// inComment = 0;
|
// inComment = 0;
|
// if (inComment)
|
// if (inComment)
|
// goto j1;
|
// goto j1;
|
if (*inptr == '.') inptr++;
|
if (*inptr == '.') inptr++;
|
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
|
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
if (token == tk_strconst)
|
if (token == tk_strconst)
|
fname = std::string(laststr);
|
fname = std::string(laststr);
|
else
|
else
|
fname = std::string("<unknown file>");
|
fname = std::string("<unknown file>");
|
NextToken();
|
NextToken();
|
lineno = expr();
|
lineno = expr();
|
setname = true;
|
setname = true;
|
}
|
}
|
else if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) {
|
else if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) {
|
segment = codeseg;
|
segment = codeseg;
|
setname = true;
|
setname = true;
|
}
|
}
|
else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) {
|
else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) {
|
segment = dataseg;
|
segment = dataseg;
|
}
|
}
|
else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) {
|
else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) {
|
segment = rodataseg;
|
segment = rodataseg;
|
}
|
}
|
else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) {
|
else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) {
|
segment = tlsseg;
|
segment = tlsseg;
|
}
|
}
|
else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) {
|
else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) {
|
segment = bssseg;
|
segment = bssseg;
|
}
|
}
|
j1:
|
j1:
|
ScanToEOL();
|
ScanToEOL();
|
inptr++;
|
inptr++;
|
switch(segment) {
|
switch(segment) {
|
case codeseg:
|
case codeseg:
|
if (setname) {
|
if (setname) {
|
setname = false;
|
setname = false;
|
if (fname.length() > 0) {
|
if (fname.length() > 0) {
|
sprintf(&codebuf[codendx], ".file \x22%s\x22,%d\n", fname.c_str(), lineno);
|
sprintf(&codebuf[codendx], ".file \x22%s\x22,%d\n", fname.c_str(), lineno);
|
codendx += strlen(&codebuf[codendx]);
|
codendx += strlen(&codebuf[codendx]);
|
}
|
}
|
}
|
}
|
strncpy(&codebuf[codendx], pinptr, inptr-pinptr);
|
strncpy(&codebuf[codendx], pinptr, inptr-pinptr);
|
codendx += inptr-pinptr;
|
codendx += inptr-pinptr;
|
break;
|
break;
|
case dataseg:
|
case dataseg:
|
strncpy(&databuf[datandx], pinptr, inptr-pinptr);
|
strncpy(&databuf[datandx], pinptr, inptr-pinptr);
|
datandx += inptr-pinptr;
|
datandx += inptr-pinptr;
|
break;
|
break;
|
case rodataseg:
|
case rodataseg:
|
strncpy(&rodatabuf[rodatandx], pinptr, inptr-pinptr);
|
strncpy(&rodatabuf[rodatandx], pinptr, inptr-pinptr);
|
rodatandx += inptr-pinptr;
|
rodatandx += inptr-pinptr;
|
break;
|
break;
|
case tlsseg:
|
case tlsseg:
|
strncpy(&tlsbuf[tlsndx], pinptr, inptr-pinptr);
|
strncpy(&tlsbuf[tlsndx], pinptr, inptr-pinptr);
|
tlsndx += inptr-pinptr;
|
tlsndx += inptr-pinptr;
|
break;
|
break;
|
case bssseg:
|
case bssseg:
|
strncpy(&bssbuf[bssndx], pinptr, inptr-pinptr);
|
strncpy(&bssbuf[bssndx], pinptr, inptr-pinptr);
|
bssndx += inptr-pinptr;
|
bssndx += inptr-pinptr;
|
break;
|
break;
|
}
|
}
|
pinptr = inptr;
|
pinptr = inptr;
|
}
|
}
|
ZeroMemory(masterFile,sizeof(masterFile));
|
ZeroMemory(masterFile,sizeof(masterFile));
|
strcat(masterFile, codebuf);
|
strcat(masterFile, codebuf);
|
strcat(masterFile, rodatabuf);
|
strcat(masterFile, rodatabuf);
|
strcat(masterFile, "\r\n\trodata\r\n");
|
strcat(masterFile, "\r\n\trodata\r\n");
|
strcat(masterFile, "\talign 8\r\n");
|
strcat(masterFile, "\talign 8\r\n");
|
strcat(masterFile, "begin_init_data:\r\n");
|
strcat(masterFile, "begin_init_data:\r\n");
|
strcat(masterFile, databuf);
|
strcat(masterFile, databuf);
|
strcat(masterFile, "\r\n\trodata\r\n");
|
strcat(masterFile, "\r\n\trodata\r\n");
|
strcat(masterFile, "\talign 8\r\n");
|
strcat(masterFile, "\talign 8\r\n");
|
strcat(masterFile, "end_init_data:\r\n");
|
strcat(masterFile, "end_init_data:\r\n");
|
strcat(masterFile, databuf);
|
strcat(masterFile, databuf);
|
strcat(masterFile, bssbuf);
|
strcat(masterFile, bssbuf);
|
strcat(masterFile, tlsbuf);
|
strcat(masterFile, tlsbuf);
|
if (debug) {
|
if (debug) {
|
FILE *fp;
|
FILE *fp;
|
fp = fopen("a64-segments.asm", "w");
|
fp = fopen("a64-segments.asm", "w");
|
if (fp) {
|
if (fp) {
|
fwrite(masterFile, 1, strlen(masterFile), fp);
|
fwrite(masterFile, 1, strlen(masterFile), fp);
|
fclose(fp);
|
fclose(fp);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void ProcessSegments2()
|
void ProcessSegments2()
|
{
|
{
|
char buf[1000];
|
char buf[1000];
|
char *lptr;
|
char *lptr;
|
char fname[600];
|
char fname[600];
|
bool setname = false;
|
bool setname = false;
|
|
|
std::ifstream ifs("as64-master.asm");
|
std::ifstream ifs("as64-master.asm");
|
std::ofstream codeofs("as64-code.asm");
|
std::ofstream codeofs("as64-code.asm");
|
std::ofstream dataofs("as64-data.asm");
|
std::ofstream dataofs("as64-data.asm");
|
std::ofstream idataofs("as64-idata.asm");
|
std::ofstream idataofs("as64-idata.asm");
|
std::ofstream rodataofs("as64-rodata.asm");
|
std::ofstream rodataofs("as64-rodata.asm");
|
std::ofstream bssofs("as64-bss.asm");
|
std::ofstream bssofs("as64-bss.asm");
|
std::ofstream tlsofs("as64-tls.asm");
|
std::ofstream tlsofs("as64-tls.asm");
|
|
|
ZeroMemory(buf, sizeof(buf));
|
ZeroMemory(buf, sizeof(buf));
|
ZeroMemory(fname, sizeof(fname));
|
ZeroMemory(fname, sizeof(fname));
|
while (ifs.getline(buf, sizeof(buf))) {
|
while (ifs.getline(buf, sizeof(buf))) {
|
inptr = buf;
|
inptr = buf;
|
SkipSpaces();
|
SkipSpaces();
|
if (*inptr == ';')
|
if (*inptr == ';')
|
goto j1;
|
goto j1;
|
if (inptr[0] == '/' && inptr[1] == '/')
|
if (inptr[0] == '/' && inptr[1] == '/')
|
goto j1;
|
goto j1;
|
if (*inptr == '.') inptr++;
|
if (*inptr == '.') inptr++;
|
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
|
if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
if (inptr[0] == ':')
|
if (inptr[0] == ':')
|
inptr++;
|
inptr++;
|
getIdentifier();
|
getIdentifier();
|
strcpy_s(fname, sizeof(fname), lastid);
|
strcpy_s(fname, sizeof(fname), lastid);
|
}
|
}
|
if ((_strnicmp(inptr, "code", 4) == 0) && !isIdentChar(inptr[4])) {
|
if ((_strnicmp(inptr, "code", 4) == 0) && !isIdentChar(inptr[4])) {
|
segment = codeseg;
|
segment = codeseg;
|
setname = true;
|
setname = true;
|
}
|
}
|
else if ((_strnicmp(inptr, "data", 4) == 0) && !isIdentChar(inptr[4])) {
|
else if ((_strnicmp(inptr, "data", 4) == 0) && !isIdentChar(inptr[4])) {
|
segment = dataseg;
|
segment = dataseg;
|
}
|
}
|
else if ((_strnicmp(inptr, "rodata", 6) == 0) && !isIdentChar(inptr[6])) {
|
else if ((_strnicmp(inptr, "rodata", 6) == 0) && !isIdentChar(inptr[6])) {
|
segment = rodataseg;
|
segment = rodataseg;
|
}
|
}
|
else if ((_strnicmp(inptr, "tls", 3) == 0) && !isIdentChar(inptr[3])) {
|
else if ((_strnicmp(inptr, "tls", 3) == 0) && !isIdentChar(inptr[3])) {
|
segment = tlsseg;
|
segment = tlsseg;
|
}
|
}
|
else if ((_strnicmp(inptr, "bss", 3) == 0) && !isIdentChar(inptr[3])) {
|
else if ((_strnicmp(inptr, "bss", 3) == 0) && !isIdentChar(inptr[3])) {
|
segment = bssseg;
|
segment = bssseg;
|
}
|
}
|
j1:
|
j1:
|
switch (segment) {
|
switch (segment) {
|
case codeseg:
|
case codeseg:
|
if (setname) {
|
if (setname) {
|
setname = false;
|
setname = false;
|
codeofs << ".file: ";
|
codeofs << ".file: ";
|
codeofs << fname;
|
codeofs << fname;
|
}
|
}
|
codeofs << buf;
|
codeofs << buf;
|
break;
|
break;
|
case dataseg:
|
case dataseg:
|
dataofs << buf;
|
dataofs << buf;
|
break;
|
break;
|
case rodataseg:
|
case rodataseg:
|
rodataofs << buf;
|
rodataofs << buf;
|
break;
|
break;
|
case tlsseg:
|
case tlsseg:
|
tlsofs << buf;
|
tlsofs << buf;
|
break;
|
break;
|
case bssseg:
|
case bssseg:
|
bssofs << buf;
|
bssofs << buf;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
codeofs.close();
|
codeofs.close();
|
dataofs.close();
|
dataofs.close();
|
idataofs.close();
|
idataofs.close();
|
rodataofs.close();
|
rodataofs.close();
|
bssofs.close();
|
bssofs.close();
|
tlsofs.close();
|
tlsofs.close();
|
ifs.close();
|
ifs.close();
|
system("type as64-code.asm > as64-segments.asm");
|
system("type as64-code.asm > as64-segments.asm");
|
system("type as64-rodata.asm >> as64-segments.asm");
|
system("type as64-rodata.asm >> as64-segments.asm");
|
std::ofstream ofs("as64-segments.asm", std::ofstream::out | std::ofstream::app);
|
std::ofstream ofs("as64-segments.asm", std::ofstream::out | std::ofstream::app);
|
ofs << "\nrodata\n";
|
ofs << "\nrodata\n";
|
ofs << "\talign 8\n";
|
ofs << "\talign 8\n";
|
ofs << "begin_init_data:\n";
|
ofs << "begin_init_data:\n";
|
ofs.close();
|
ofs.close();
|
system("type as64-data.asm >> as64-segments.asm");
|
system("type as64-data.asm >> as64-segments.asm");
|
ofs.open("as64-segments.asm", std::ofstream::out | std::ofstream::app);
|
ofs.open("as64-segments.asm", std::ofstream::out | std::ofstream::app);
|
ofs << "\nrodata\n";
|
ofs << "\nrodata\n";
|
ofs << "\talign 8\n";
|
ofs << "\talign 8\n";
|
ofs << "end_init_data:\n";
|
ofs << "end_init_data:\n";
|
ofs.close();
|
ofs.close();
|
system("type as64-data.asm >> as64-segments.asm");
|
system("type as64-data.asm >> as64-segments.asm");
|
system("type as64-bss.asm >> as64-segments.asm");
|
system("type as64-bss.asm >> as64-segments.asm");
|
system("type as64-tls.asm >> as64-segments.asm");
|
system("type as64-tls.asm >> as64-segments.asm");
|
}
|
}
|
|
|
void skipif(int64_t val)
|
void skipif(int64_t val)
|
{
|
{
|
int iflevel = 1;
|
int iflevel = 1;
|
char *p1, *p2, *p3;
|
char *p1, *p2, *p3;
|
bool codecut = false;
|
bool codecut = false;
|
|
|
// Cut out the if statement
|
// Cut out the if statement
|
p1 = pif1;
|
p1 = pif1;
|
memmove(pif1,pif2,sizeof(masterFile)-(pif2-masterFile));
|
memmove(pif1,pif2,masterFileLength-(pif2-masterFile));
|
|
|
p1 = inptr = pif1;
|
p1 = inptr = pif1;
|
while(*inptr) {
|
while(*inptr) {
|
SkipSpaces();
|
SkipSpaces();
|
p2 = inptr;
|
p2 = inptr;
|
NextToken();
|
NextToken();
|
p3 = inptr;
|
p3 = inptr;
|
if (token==tk_if || token==tk_ifdef || token==tk_ifndef)
|
if (token==tk_if || token==tk_ifdef || token==tk_ifndef)
|
iflevel++;
|
iflevel++;
|
else if (token==tk_endif) {
|
else if (token==tk_endif) {
|
iflevel--;
|
iflevel--;
|
if (iflevel==0) {
|
if (iflevel==0) {
|
// If the if was false cut out the code between
|
// If the if was false cut out the code between
|
// if and endif
|
// if and endif
|
if (val==0 && !codecut) {
|
if (val==0 && !codecut) {
|
memmove(pif1,p3,sizeof(masterFile)-(p3-masterFile));
|
memmove(pif1,p3,masterFileLength-(p3-masterFile));
|
inptr = pif1;
|
inptr = pif1;
|
return;
|
return;
|
}
|
}
|
else {
|
else {
|
// remove endif but leave remaining text
|
// remove endif but leave remaining text
|
memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
|
memmove(p2,inptr,masterFileLength-(inptr-masterFile));
|
inptr = p2;
|
inptr = p2;
|
}
|
}
|
}
|
}
|
}
|
}
|
else if (token==tk_else) {
|
else if (token==tk_else) {
|
if (iflevel==0) {
|
if (iflevel==0) {
|
// cut out code between if and else
|
// cut out code between if and else
|
// and keep going until endif
|
// and keep going until endif
|
if (val==0) {
|
if (val==0) {
|
memmove(pif1,p2+4,sizeof(masterFile)-(p2+4-masterFile));
|
memmove(pif1,p2+4,masterFileLength-(p2+4-masterFile));
|
inptr = pif1;
|
inptr = pif1;
|
codecut = true;
|
codecut = true;
|
}
|
}
|
else {
|
else {
|
// remove the else from text
|
// remove the else from text
|
// and keep going until endif
|
// and keep going until endif
|
memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
|
memmove(p2,inptr,masterFileLength-(inptr-masterFile));
|
inptr = p2;
|
inptr = p2;
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
ScanToEOL();
|
ScanToEOL();
|
if (*inptr=='\n')
|
if (*inptr=='\n')
|
inptr++;
|
inptr++;
|
}
|
}
|
}
|
}
|
|
|
void doif()
|
void doif()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
pif2 = inptr;
|
pif2 = inptr;
|
ScanToEOL();
|
ScanToEOL();
|
skipif(val);
|
skipif(val);
|
}
|
}
|
|
|
void doifdef()
|
void doifdef()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
|
SkipSpaces();
|
if (getIdentifier()==0)
|
if (getIdentifier()==0)
|
printf("Expecting an identifier %d.\n", lineno);
|
printf("Expecting an identifier %d.\n", lineno);
|
val = (find_symbol(lastid)!=nullptr);
|
val = (find_symbol(lastid)!=nullptr);
|
ScanToEOL();
|
|
pif2 = inptr;
|
pif2 = inptr;
|
|
ScanToEOL();
|
skipif(val);
|
skipif(val);
|
}
|
}
|
|
|
void doifndef()
|
void doifndef()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
if (getIdentifier()==0)
|
if (getIdentifier()==0)
|
printf("Expecting an identifier %d.\n", lineno);
|
printf("Expecting an identifier %d.\n", lineno);
|
val = (find_symbol(lastid)==nullptr);
|
val = (find_symbol(lastid)==nullptr);
|
ScanToEOL();
|
ScanToEOL();
|
pif2 = inptr;
|
pif2 = inptr;
|
skipif(val);
|
skipif(val);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Look for .include directives and include the files.
|
// Look for .include directives and include the files.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void processLine(char *line)
|
void processLine(char *line)
|
{
|
{
|
char *p;
|
char *p;
|
int quoteType;
|
int quoteType;
|
static char fnm[300];
|
static char fnm[300];
|
char *fname;
|
char *fname;
|
int nn;
|
int nn;
|
int lb;
|
int lb;
|
|
|
p = line;
|
p = line;
|
fns.GetTos()->lineno = lineno;
|
fns.GetTos()->lineno = lineno;
|
while(isspace(*p)) p++;
|
while(isspace(*p)) p++;
|
if (!*p) goto addToMaster;
|
if (!*p) goto addToMaster;
|
// see if the first thing on the line is an include directive
|
// see if the first thing on the line is an include directive
|
if (*p=='.') p++;
|
if (*p=='.') p++;
|
if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7]))
|
if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7]))
|
{
|
{
|
p += 7;
|
p += 7;
|
// Capture the file name
|
// Capture the file name
|
while(isspace(*p)) p++;
|
while(isspace(*p)) p++;
|
if (*p=='"') { quoteType = '"'; p++; }
|
if (*p=='"') { quoteType = '"'; p++; }
|
else if (*p=='<') { quoteType = '>'; p++; }
|
else if (*p=='<') { quoteType = '>'; p++; }
|
else quoteType = ' ';
|
else quoteType = ' ';
|
nn = 0;
|
nn = 0;
|
do {
|
do {
|
fnm[nn] = *p;
|
fnm[nn] = *p;
|
p++; nn++;
|
p++; nn++;
|
if (quoteType==' ' && isspace(*p)) break;
|
if (quoteType==' ' && isspace(*p)) break;
|
else if (*p == quoteType) break;
|
else if (*p == quoteType) break;
|
else if (*p=='\n') break;
|
else if (*p=='\n') break;
|
} while(nn < sizeof(fnm)/sizeof(char));
|
} while(nn < sizeof(fnm)/sizeof(char));
|
fnm[nn] = '\0';
|
fnm[nn] = '\0';
|
fname = strdup(fnm);
|
fname = strdup(fnm);
|
lb = lineno;
|
lb = lineno;
|
lineno = 1;
|
lineno = 1;
|
processFile(fname,1);
|
processFile(fname,1);
|
lineno = lb;
|
lineno = lb;
|
free(fname);
|
free(fname);
|
return;
|
return;
|
}
|
}
|
// Not an include directive, then just copy the line to the master buffer.
|
// Not an include directive, then just copy the line to the master buffer.
|
addToMaster:
|
addToMaster:
|
//strcpy(&masterFile[mfndx], line);
|
//strcpy(&masterFile[mfndx], line);
|
//mfndx += strlen(line);
|
//mfndx += strlen(line);
|
mofs << line;
|
mofs << line;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Build a aggregate of all the included files into a single master buffer.
|
// Build a aggregate of all the included files into a single master buffer.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void processFile(char *fname, int searchincl)
|
void processFile(char *fname, int searchincl)
|
{
|
{
|
FILE *fp;
|
FILE *fp;
|
std::ifstream ifs;
|
std::ifstream ifs;
|
char *pathname;
|
char *pathname;
|
char buf[700];
|
char buf[700];
|
|
|
fns.Push(mname, lineno);
|
fns.Push(mname, lineno);
|
mname = std::string(fname);
|
mname = std::string(fname);
|
lineno = 1;
|
lineno = 1;
|
mofs << ".file \x22";
|
mofs << ".file \x22";
|
mofs << mname.c_str();
|
mofs << mname.c_str();
|
mofs << "\x22," << lineno << "\n";
|
mofs << "\x22," << lineno << "\n";
|
if (verbose)
|
if (verbose)
|
printf("Processing file:%s\n", fname);
|
printf("Processing file:%s\n", fname);
|
pathname = (char *)NULL;
|
pathname = (char *)NULL;
|
ifs.open(fname);
|
ifs.open(fname);
|
if (ifs.fail()) {
|
if (ifs.fail()) {
|
if (searchincl) {
|
if (searchincl) {
|
searchenv(fname, "INCLUDE", &pathname);
|
searchenv(fname, "INCLUDE", &pathname);
|
if (strlen(pathname)) {
|
if (strlen(pathname)) {
|
ifs.open(pathname);
|
ifs.open(pathname);
|
if (!ifs.fail()) goto j1;
|
if (!ifs.fail()) goto j1;
|
}
|
}
|
}
|
}
|
printf("Can't open file <%s>\n", fname);
|
printf("Can't open file <%s>\n", fname);
|
goto j2;
|
goto j2;
|
}
|
}
|
j1:
|
j1:
|
while (ifs.getline(buf, sizeof(buf))) {
|
while (ifs.getline(buf, sizeof(buf))) {
|
strcat(buf,"\n");
|
strcat(buf,"\n");
|
processLine(buf);
|
processLine(buf);
|
}
|
}
|
ifs.close();
|
ifs.close();
|
j2:
|
j2:
|
if (pathname)
|
if (pathname)
|
free(pathname);
|
free(pathname);
|
fns.Pop(&mname, &lineno);
|
fns.Pop(&mname, &lineno);
|
mofs << ".file \x22";
|
mofs << ".file \x22";
|
mofs << mname.c_str();
|
mofs << mname.c_str();
|
mofs << "\x22," << lineno << "\n";
|
mofs << "\x22," << lineno << "\n";
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
int checksum(int32_t *val)
|
int checksum(int32_t *val)
|
{
|
{
|
int nn;
|
int nn;
|
int cs;
|
int cs;
|
|
|
cs = 0;
|
cs = 0;
|
for (nn = 0; nn < 32; nn++)
|
for (nn = 0; nn < 32; nn++)
|
cs ^= (*val & (1 << nn))!=0;
|
cs ^= (*val & (1 << nn))!=0;
|
return cs;
|
return cs;
|
}
|
}
|
|
|
|
|
int checksum64(int64_t *val)
|
int checksum64(int64_t *val)
|
{
|
{
|
int nn;
|
int nn;
|
int cs;
|
int cs;
|
|
|
cs = 0;
|
cs = 0;
|
for (nn = 0; nn < 64; nn++)
|
for (nn = 0; nn < 64; nn++)
|
cs ^= (*val & (1LL << nn))!=0;
|
cs ^= (*val & (1LL << nn))!=0;
|
return cs;
|
return cs;
|
}
|
}
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void processMaster()
|
void processMaster()
|
{
|
{
|
expandedBlock = 0;
|
expandedBlock = 0;
|
switch(gCpu) {
|
switch(gCpu) {
|
case 888: Table888_processMaster(); break;
|
case 888: Table888_processMaster(); break;
|
case 889: Table888mmu_processMaster(); break;
|
case 889: Table888mmu_processMaster(); break;
|
case 64: FISA64_processMaster(); break;
|
case 64: FISA64_processMaster(); break;
|
case 5: Friscv_processMaster(); break;
|
case 5: Friscv_processMaster(); break;
|
case 4: Thor_processMaster(); break;
|
case 4: Thor_processMaster(); break;
|
case 14: dsd6_processMaster(); break;
|
case 14: dsd6_processMaster(); break;
|
case 7: dsd7_processMaster(); break;
|
case 7: dsd7_processMaster(); break;
|
case 'A': dsd9_processMaster(); break;
|
case 'A': dsd9_processMaster(); break;
|
case 'F': FT64_processMaster(); break;
|
case 'F': FT64_processMaster(); break;
|
case 'G': FT64x36_processMaster(); break;
|
case 'G': FT64x36_processMaster(); break;
|
default: FT64_processMaster();
|
default: FT64_processMaster();
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
int64_t Round512(int64_t n)
|
int64_t Round512(int64_t n)
|
{
|
{
|
return (n + 511LL) & 0xFFFFFFFFFFFFFE00LL;
|
return (n + 511LL) & 0xFFFFFFFFFFFFFE00LL;
|
}
|
}
|
|
|
int64_t Round4096(int64_t n)
|
int64_t Round4096(int64_t n)
|
{
|
{
|
return (n + 4095LL) & 0xFFFFFFFFFFFFF000LL;
|
return (n + 4095LL) & 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void WriteELFFile(FILE *fp)
|
void WriteELFFile(FILE *fp)
|
{
|
{
|
int nn;
|
int nn;
|
Elf64Symbol elfsym;
|
Elf64Symbol elfsym;
|
clsElf64File elf;
|
clsElf64File elf;
|
SYM *sym,*syms;
|
SYM *sym,*syms;
|
int64_t start;
|
int64_t start;
|
|
|
sections[0].hdr.sh_name = nmTable.AddName(".text");
|
sections[0].hdr.sh_name = nmTable.AddName(".text");
|
sections[0].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[0].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[0].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_EXECINSTR;
|
sections[0].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_EXECINSTR;
|
sections[0].hdr.sh_addr = rel_out ? 0 : sections[0].start;
|
sections[0].hdr.sh_addr = rel_out ? 0 : sections[0].start;
|
sections[0].hdr.sh_offset = 512; // offset in file
|
sections[0].hdr.sh_offset = 512; // offset in file
|
sections[0].hdr.sh_size = sections[0].index;
|
sections[0].hdr.sh_size = sections[0].index;
|
sections[0].hdr.sh_link = 0;
|
sections[0].hdr.sh_link = 0;
|
sections[0].hdr.sh_info = 0;
|
sections[0].hdr.sh_info = 0;
|
sections[0].hdr.sh_addralign = 16;
|
sections[0].hdr.sh_addralign = 16;
|
sections[0].hdr.sh_entsize = 0;
|
sections[0].hdr.sh_entsize = 0;
|
|
|
sections[1].hdr.sh_name = nmTable.AddName(".rodata");
|
sections[1].hdr.sh_name = nmTable.AddName(".rodata");
|
sections[1].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[1].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[1].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC;
|
sections[1].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC;
|
sections[1].hdr.sh_addr = sections[0].hdr.sh_addr + sections[0].index;
|
sections[1].hdr.sh_addr = sections[0].hdr.sh_addr + sections[0].index;
|
sections[1].hdr.sh_offset = sections[0].hdr.sh_offset + sections[0].index; // offset in file
|
sections[1].hdr.sh_offset = sections[0].hdr.sh_offset + sections[0].index; // offset in file
|
sections[1].hdr.sh_size = sections[1].index;
|
sections[1].hdr.sh_size = sections[1].index;
|
sections[1].hdr.sh_link = 0;
|
sections[1].hdr.sh_link = 0;
|
sections[1].hdr.sh_info = 0;
|
sections[1].hdr.sh_info = 0;
|
sections[1].hdr.sh_addralign = 8;
|
sections[1].hdr.sh_addralign = 8;
|
sections[1].hdr.sh_entsize = 0;
|
sections[1].hdr.sh_entsize = 0;
|
|
|
sections[2].hdr.sh_name = nmTable.AddName(".data");
|
sections[2].hdr.sh_name = nmTable.AddName(".data");
|
sections[2].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[2].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[2].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[2].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[2].hdr.sh_addr = sections[1].hdr.sh_addr + sections[1].index;
|
sections[2].hdr.sh_addr = sections[1].hdr.sh_addr + sections[1].index;
|
sections[2].hdr.sh_offset = sections[1].hdr.sh_offset + sections[1].index; // offset in file
|
sections[2].hdr.sh_offset = sections[1].hdr.sh_offset + sections[1].index; // offset in file
|
sections[2].hdr.sh_size = sections[2].index;
|
sections[2].hdr.sh_size = sections[2].index;
|
sections[2].hdr.sh_link = 0;
|
sections[2].hdr.sh_link = 0;
|
sections[2].hdr.sh_info = 0;
|
sections[2].hdr.sh_info = 0;
|
sections[2].hdr.sh_addralign = 8;
|
sections[2].hdr.sh_addralign = 8;
|
sections[2].hdr.sh_entsize = 0;
|
sections[2].hdr.sh_entsize = 0;
|
|
|
sections[3].hdr.sh_name = nmTable.AddName(".bss");
|
sections[3].hdr.sh_name = nmTable.AddName(".bss");
|
sections[3].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[3].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[3].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[3].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[3].hdr.sh_addr = sections[2].hdr.sh_addr + sections[2].index;
|
sections[3].hdr.sh_addr = sections[2].hdr.sh_addr + sections[2].index;
|
sections[3].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
|
sections[3].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
|
sections[3].hdr.sh_size = 0;
|
sections[3].hdr.sh_size = 0;
|
sections[3].hdr.sh_link = 0;
|
sections[3].hdr.sh_link = 0;
|
sections[3].hdr.sh_info = 0;
|
sections[3].hdr.sh_info = 0;
|
sections[3].hdr.sh_addralign = 8;
|
sections[3].hdr.sh_addralign = 8;
|
sections[3].hdr.sh_entsize = 0;
|
sections[3].hdr.sh_entsize = 0;
|
|
|
sections[4].hdr.sh_name = nmTable.AddName(".tls");
|
sections[4].hdr.sh_name = nmTable.AddName(".tls");
|
sections[4].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[4].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
|
sections[4].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[4].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
|
sections[4].hdr.sh_addr = sections[3].hdr.sh_addr + sections[3].index;;
|
sections[4].hdr.sh_addr = sections[3].hdr.sh_addr + sections[3].index;;
|
sections[4].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
|
sections[4].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
|
sections[4].hdr.sh_size = 0;
|
sections[4].hdr.sh_size = 0;
|
sections[4].hdr.sh_link = 0;
|
sections[4].hdr.sh_link = 0;
|
sections[4].hdr.sh_info = 0;
|
sections[4].hdr.sh_info = 0;
|
sections[4].hdr.sh_addralign = 8;
|
sections[4].hdr.sh_addralign = 8;
|
sections[4].hdr.sh_entsize = 0;
|
sections[4].hdr.sh_entsize = 0;
|
|
|
sections[5].hdr.sh_name = nmTable.AddName(".strtab");
|
sections[5].hdr.sh_name = nmTable.AddName(".strtab");
|
// The following line must be before the name table is copied to the section.
|
// The following line must be before the name table is copied to the section.
|
sections[6].hdr.sh_name = nmTable.AddName(".symtab");
|
sections[6].hdr.sh_name = nmTable.AddName(".symtab");
|
sections[7].hdr.sh_name = nmTable.AddName(".reltext");
|
sections[7].hdr.sh_name = nmTable.AddName(".reltext");
|
sections[8].hdr.sh_name = nmTable.AddName(".relrodata");
|
sections[8].hdr.sh_name = nmTable.AddName(".relrodata");
|
sections[9].hdr.sh_name = nmTable.AddName(".reldata");
|
sections[9].hdr.sh_name = nmTable.AddName(".reldata");
|
sections[10].hdr.sh_name = nmTable.AddName(".relbss");
|
sections[10].hdr.sh_name = nmTable.AddName(".relbss");
|
sections[11].hdr.sh_name = nmTable.AddName(".reltls");
|
sections[11].hdr.sh_name = nmTable.AddName(".reltls");
|
sections[5].hdr.sh_type = clsElf64Shdr::SHT_STRTAB;
|
sections[5].hdr.sh_type = clsElf64Shdr::SHT_STRTAB;
|
sections[5].hdr.sh_flags = 0;
|
sections[5].hdr.sh_flags = 0;
|
sections[5].hdr.sh_addr = 0;
|
sections[5].hdr.sh_addr = 0;
|
sections[5].hdr.sh_offset = 512 + sections[0].index + sections[1].index + sections[2].index; // offset in file
|
sections[5].hdr.sh_offset = 512 + sections[0].index + sections[1].index + sections[2].index; // offset in file
|
sections[5].hdr.sh_size = nmTable.length;
|
sections[5].hdr.sh_size = nmTable.length;
|
sections[5].hdr.sh_link = 0;
|
sections[5].hdr.sh_link = 0;
|
sections[5].hdr.sh_info = 0;
|
sections[5].hdr.sh_info = 0;
|
sections[5].hdr.sh_addralign = 1;
|
sections[5].hdr.sh_addralign = 1;
|
sections[5].hdr.sh_entsize = 0;
|
sections[5].hdr.sh_entsize = 0;
|
memcpy(sections[5].bytes, nmTable.text, nmTable.length);
|
memcpy(sections[5].bytes, nmTable.text, nmTable.length);
|
|
|
sections[6].hdr.sh_type = clsElf64Shdr::SHT_SYMTAB;
|
sections[6].hdr.sh_type = clsElf64Shdr::SHT_SYMTAB;
|
sections[6].hdr.sh_flags = 0;
|
sections[6].hdr.sh_flags = 0;
|
sections[6].hdr.sh_addr = 0;
|
sections[6].hdr.sh_addr = 0;
|
sections[6].hdr.sh_offset = Round512(512 + sections[0].index + sections[1].index + sections[2].index) + nmTable.length; // offset in file
|
sections[6].hdr.sh_offset = Round512(512 + sections[0].index + sections[1].index + sections[2].index) + nmTable.length; // offset in file
|
sections[6].hdr.sh_size = (numsym + 1) * 24;
|
sections[6].hdr.sh_size = (numsym + 1) * 24;
|
sections[6].hdr.sh_link = 5;
|
sections[6].hdr.sh_link = 5;
|
sections[6].hdr.sh_info = 0;
|
sections[6].hdr.sh_info = 0;
|
sections[6].hdr.sh_addralign = 1;
|
sections[6].hdr.sh_addralign = 1;
|
sections[6].hdr.sh_entsize = 24;
|
sections[6].hdr.sh_entsize = 24;
|
|
|
for(nn = 7; nn < 12; nn++) {
|
for(nn = 7; nn < 12; nn++) {
|
sections[nn].hdr.sh_type = clsElf64Shdr::SHT_REL;
|
sections[nn].hdr.sh_type = clsElf64Shdr::SHT_REL;
|
sections[nn].hdr.sh_flags = 0;
|
sections[nn].hdr.sh_flags = 0;
|
sections[nn].hdr.sh_addr = 0;
|
sections[nn].hdr.sh_addr = 0;
|
sections[nn].hdr.sh_offset = sections[nn-1].hdr.sh_offset + sections[nn-1].hdr.sh_size; // offset in file
|
sections[nn].hdr.sh_offset = sections[nn-1].hdr.sh_offset + sections[nn-1].hdr.sh_size; // offset in file
|
sections[nn].hdr.sh_size = sections[nn].index;
|
sections[nn].hdr.sh_size = sections[nn].index;
|
sections[nn].hdr.sh_link = 6;
|
sections[nn].hdr.sh_link = 6;
|
sections[nn].hdr.sh_info = 0;
|
sections[nn].hdr.sh_info = 0;
|
sections[nn].hdr.sh_addralign = 1;
|
sections[nn].hdr.sh_addralign = 1;
|
sections[nn].hdr.sh_entsize = 16;
|
sections[nn].hdr.sh_entsize = 16;
|
}
|
}
|
|
|
nn = 1;
|
nn = 1;
|
// The first entry is an NULL symbol
|
// The first entry is an NULL symbol
|
elfsym.st_name = 0;
|
elfsym.st_name = 0;
|
elfsym.st_info = 0;
|
elfsym.st_info = 0;
|
elfsym.st_other = 0;
|
elfsym.st_other = 0;
|
elfsym.st_shndx = 0;
|
elfsym.st_shndx = 0;
|
elfsym.st_value = 0;
|
elfsym.st_value = 0;
|
elfsym.st_size = 0;
|
elfsym.st_size = 0;
|
sections[6].Add(&elfsym);
|
sections[6].Add(&elfsym);
|
syms = (SYM*)HashInfo.table;
|
syms = (SYM*)HashInfo.table;
|
for (nn = 0; nn < HashInfo.size; nn++) {
|
for (nn = 0; nn < HashInfo.size; nn++) {
|
// Don't output the constants
|
// Don't output the constants
|
// if (syms[nn].segment < 5) {
|
// if (syms[nn].segment < 5) {
|
if (syms[nn].name) {
|
if (syms[nn].name) {
|
elfsym.st_name = syms[nn].name;
|
elfsym.st_name = syms[nn].name;
|
elfsym.st_info = syms[nn].scope == 'P' ? STB_GLOBAL << 4 : 0;
|
elfsym.st_info = syms[nn].scope == 'P' ? STB_GLOBAL << 4 : 0;
|
elfsym.st_other = 0;
|
elfsym.st_other = 0;
|
elfsym.st_shndx = syms[nn].segment;
|
elfsym.st_shndx = syms[nn].segment;
|
elfsym.st_value = syms[nn].value.low;
|
elfsym.st_value = syms[nn].value.low;
|
elfsym.st_size = 8;
|
elfsym.st_size = 8;
|
sections[6].Add(&elfsym);
|
sections[6].Add(&elfsym);
|
// }
|
// }
|
}
|
}
|
}
|
}
|
|
|
elf.hdr.e_ident[0] = 127;
|
elf.hdr.e_ident[0] = 127;
|
elf.hdr.e_ident[1] = 'E';
|
elf.hdr.e_ident[1] = 'E';
|
elf.hdr.e_ident[2] = 'L';
|
elf.hdr.e_ident[2] = 'L';
|
elf.hdr.e_ident[3] = 'F';
|
elf.hdr.e_ident[3] = 'F';
|
elf.hdr.e_ident[4] = clsElf64Header::ELFCLASS64; // 64 bit file format
|
elf.hdr.e_ident[4] = clsElf64Header::ELFCLASS64; // 64 bit file format
|
elf.hdr.e_ident[5] = clsElf64Header::ELFDATA2LSB; // little endian
|
elf.hdr.e_ident[5] = clsElf64Header::ELFDATA2LSB; // little endian
|
elf.hdr.e_ident[6] = 1; // header version always 1
|
elf.hdr.e_ident[6] = 1; // header version always 1
|
elf.hdr.e_ident[7] = 255; // OS/ABI indentification, 255 = standalone
|
elf.hdr.e_ident[7] = 255; // OS/ABI indentification, 255 = standalone
|
elf.hdr.e_ident[8] = 255; // ABI version
|
elf.hdr.e_ident[8] = 255; // ABI version
|
elf.hdr.e_ident[9] = 0;
|
elf.hdr.e_ident[9] = 0;
|
elf.hdr.e_ident[10] = 0;
|
elf.hdr.e_ident[10] = 0;
|
elf.hdr.e_ident[11] = 0;
|
elf.hdr.e_ident[11] = 0;
|
elf.hdr.e_ident[12] = 0;
|
elf.hdr.e_ident[12] = 0;
|
elf.hdr.e_ident[13] = 0;
|
elf.hdr.e_ident[13] = 0;
|
elf.hdr.e_ident[14] = 0;
|
elf.hdr.e_ident[14] = 0;
|
elf.hdr.e_ident[15] = 0;
|
elf.hdr.e_ident[15] = 0;
|
elf.hdr.e_type = rel_out ? 1 : 2;
|
elf.hdr.e_type = rel_out ? 1 : 2;
|
elf.hdr.e_machine = 888; // machine architecture
|
elf.hdr.e_machine = 888; // machine architecture
|
elf.hdr.e_version = 1;
|
elf.hdr.e_version = 1;
|
sym = find_symbol("start");
|
sym = find_symbol("start");
|
if (sym)
|
if (sym)
|
start = sym->value.low;
|
start = sym->value.low;
|
else
|
else
|
start = 0xC00200;
|
start = 0xC00200;
|
elf.hdr.e_entry = start;
|
elf.hdr.e_entry = start;
|
elf.hdr.e_phoff = 0;
|
elf.hdr.e_phoff = 0;
|
elf.hdr.e_shoff = sections[11].hdr.sh_offset + sections[11].index;
|
elf.hdr.e_shoff = sections[11].hdr.sh_offset + sections[11].index;
|
elf.hdr.e_flags = 0;
|
elf.hdr.e_flags = 0;
|
elf.hdr.e_ehsize = Elf64HdrSz;
|
elf.hdr.e_ehsize = Elf64HdrSz;
|
elf.hdr.e_phentsize = 0;
|
elf.hdr.e_phentsize = 0;
|
elf.hdr.e_phnum = 0;
|
elf.hdr.e_phnum = 0;
|
elf.hdr.e_shentsize = Elf64ShdrSz;
|
elf.hdr.e_shentsize = Elf64ShdrSz;
|
elf.hdr.e_shnum = 0; // This will be incremented by AddSection()
|
elf.hdr.e_shnum = 0; // This will be incremented by AddSection()
|
elf.hdr.e_shstrndx = 5; // index into section table of string table header
|
elf.hdr.e_shstrndx = 5; // index into section table of string table header
|
|
|
for (nn = 0; nn < 12; nn++)
|
for (nn = 0; nn < 12; nn++)
|
elf.AddSection(§ions[nn]);
|
elf.AddSection(§ions[nn]);
|
elf.Write(fp);
|
elf.Write(fp);
|
|
|
}
|
}
|
|
|
int IHChecksum(char *ibuf, int payloadCount)
|
int IHChecksum(char *ibuf, int payloadCount)
|
{
|
{
|
char buf[20];
|
char buf[20];
|
int nn;
|
int nn;
|
int ii;
|
int ii;
|
int sum;
|
int sum;
|
|
|
sum = 0;
|
sum = 0;
|
for (nn = 0; nn < payloadCount +4; nn++) {
|
for (nn = 0; nn < payloadCount +4; nn++) {
|
buf[0] = ibuf[nn*2+1];
|
buf[0] = ibuf[nn*2+1];
|
buf[1] = ibuf[nn*2+2];
|
buf[1] = ibuf[nn*2+2];
|
buf[2] = '\0';
|
buf[2] = '\0';
|
ii = strtoul(buf,NULL,16);
|
ii = strtoul(buf,NULL,16);
|
sum = sum + ii;
|
sum = sum + ii;
|
}
|
}
|
sum = -sum;
|
sum = -sum;
|
sprintf(&ibuf[(payloadCount+4) * 2+1],"%02X\n", sum & 0xFF);
|
sprintf(&ibuf[(payloadCount+4) * 2+1],"%02X\n", sum & 0xFF);
|
return sum;
|
return sum;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
int64_t getbit(int n, int bit)
|
int64_t getbit(int n, int bit)
|
{
|
{
|
return (n >> bit) & 1;
|
return (n >> bit) & 1;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Compute 38 bit ECC (32+6 bits EDC).
|
// Compute 38 bit ECC (32+6 bits EDC).
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
int checkbits(unsigned int i)
|
int checkbits(unsigned int i)
|
{
|
{
|
/*
|
/*
|
unsigned int p0,p1,p2,p3,p4,p5,p;
|
unsigned int p0,p1,p2,p3,p4,p5,p;
|
unsigned int t1,t2,t3;
|
unsigned int t1,t2,t3;
|
|
|
p0 = u ^ (u >> 2);
|
p0 = u ^ (u >> 2);
|
p0 = p0 ^ (p0 >> 4);
|
p0 = p0 ^ (p0 >> 4);
|
p0 = p0 ^ (p0 >> 8);
|
p0 = p0 ^ (p0 >> 8);
|
p0 = p0 ^ (p0 >> 16);
|
p0 = p0 ^ (p0 >> 16);
|
|
|
t1 = u ^ (u >> 1);
|
t1 = u ^ (u >> 1);
|
p1 = t1 ^ (t1 >> 4);
|
p1 = t1 ^ (t1 >> 4);
|
p1 = p1 ^ (p1 >> 8);
|
p1 = p1 ^ (p1 >> 8);
|
p1 = p1 ^ (p1 >> 16);
|
p1 = p1 ^ (p1 >> 16);
|
|
|
t2 = t1 ^ (t1 >> 2);
|
t2 = t1 ^ (t1 >> 2);
|
p2 = t2 ^ (t2 >> 8);
|
p2 = t2 ^ (t2 >> 8);
|
p2 = p2 ^ (p2 >> 16);
|
p2 = p2 ^ (p2 >> 16);
|
|
|
t3 = t2 ^ (t2 >> 4);
|
t3 = t2 ^ (t2 >> 4);
|
p3 = t3 ^ (t3 >> 16);
|
p3 = t3 ^ (t3 >> 16);
|
|
|
p4 = t3 ^ (t3 >> 8);
|
p4 = t3 ^ (t3 >> 8);
|
|
|
p5 = p4 ^ (p4 >> 16);
|
p5 = p4 ^ (p4 >> 16);
|
|
|
p = ((p0 >> 1)&1) | ((p1 >> 1)&2) | ((p2>>2)&4) |
|
p = ((p0 >> 1)&1) | ((p1 >> 1)&2) | ((p2>>2)&4) |
|
((p3 >> 5)&8) | ((p4 >> 12)&16) | ((p5 & 1)<<5);
|
((p3 >> 5)&8) | ((p4 >> 12)&16) | ((p5 & 1)<<5);
|
|
|
p = p ^ (-(u & 1)&0x3f); // now account for u[0]
|
p = p ^ (-(u & 1)&0x3f); // now account for u[0]
|
return p;
|
return p;
|
*/
|
*/
|
|
|
static int8_t g1[18] = {0,1,3,4,6,8,10,11,13,15,17,19,21,23,25,26,28,30};
|
static int8_t g1[18] = {0,1,3,4,6,8,10,11,13,15,17,19,21,23,25,26,28,30};
|
static int8_t g2[18] = {0,2,3,5,6,9,10,12,13,16,17,20,21,24,25,27,28,31};
|
static int8_t g2[18] = {0,2,3,5,6,9,10,12,13,16,17,20,21,24,25,27,28,31};
|
static int8_t g4[18] = {1,2,3,7,8,9,10,14,15,16,17,22,23,24,25,29,30,31};
|
static int8_t g4[18] = {1,2,3,7,8,9,10,14,15,16,17,22,23,24,25,29,30,31};
|
static int8_t g8[15] = {4,5,6,7,8,9,10,18,19,20,21,22,23,24,25};
|
static int8_t g8[15] = {4,5,6,7,8,9,10,18,19,20,21,22,23,24,25};
|
static int8_t g16[15] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
|
static int8_t g16[15] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
|
static int8_t g32[6] = {26,27,28,29,30,31};
|
static int8_t g32[6] = {26,27,28,29,30,31};
|
unsigned int p1,p2,p4,p8,p16,p32,pg,b,o;
|
unsigned int p1,p2,p4,p8,p16,p32,pg,b,o;
|
int nn;
|
int nn;
|
|
|
p1 = 0;
|
p1 = 0;
|
for (nn = 0; nn < 18; nn++) {
|
for (nn = 0; nn < 18; nn++) {
|
b = getbit(i,g1[nn]);
|
b = getbit(i,g1[nn]);
|
p1 = p1 ^ b;
|
p1 = p1 ^ b;
|
}
|
}
|
p2 = 0;
|
p2 = 0;
|
for (nn = 0; nn < 18; nn++) {
|
for (nn = 0; nn < 18; nn++) {
|
b = getbit(i,g2[nn]);
|
b = getbit(i,g2[nn]);
|
p2 = p2 ^ b;
|
p2 = p2 ^ b;
|
}
|
}
|
p4 = 0;
|
p4 = 0;
|
for (nn = 0; nn < 18; nn++) {
|
for (nn = 0; nn < 18; nn++) {
|
b = getbit(i,g4[nn]);
|
b = getbit(i,g4[nn]);
|
p4 = p4 ^ b;
|
p4 = p4 ^ b;
|
}
|
}
|
p8 = 0;
|
p8 = 0;
|
for (nn = 0; nn < 15; nn++) {
|
for (nn = 0; nn < 15; nn++) {
|
b = getbit(i,g8[nn]);
|
b = getbit(i,g8[nn]);
|
p8 = p8 ^ b;
|
p8 = p8 ^ b;
|
}
|
}
|
p16 = 0;
|
p16 = 0;
|
for (nn = 0; nn < 15; nn++) {
|
for (nn = 0; nn < 15; nn++) {
|
b = getbit(i,g16[nn]);
|
b = getbit(i,g16[nn]);
|
p16 = p16 ^ b;
|
p16 = p16 ^ b;
|
}
|
}
|
p32 = 0;
|
p32 = 0;
|
for (nn = 0; nn < 6; nn++) {
|
for (nn = 0; nn < 6; nn++) {
|
b = getbit(i,g32[nn]);
|
b = getbit(i,g32[nn]);
|
p32 = p32 ^ b;
|
p32 = p32 ^ b;
|
}
|
}
|
/*
|
/*
|
o = p1|(p2<<1)|(getbit(i,0)<<2)|(p4<<3);
|
o = p1|(p2<<1)|(getbit(i,0)<<2)|(p4<<3);
|
o = o | (getbit(i,1)<<4)| (getbit(i,2)<<5)| (getbit(i,3)<<6)|(p8<<7);
|
o = o | (getbit(i,1)<<4)| (getbit(i,2)<<5)| (getbit(i,3)<<6)|(p8<<7);
|
for (nn = 4; nn <= 10; nn++)
|
for (nn = 4; nn <= 10; nn++)
|
o = o | (getbit(i,nn)<<(nn+4));
|
o = o | (getbit(i,nn)<<(nn+4));
|
o = o | (p16 << 15);
|
o = o | (p16 << 15);
|
for (nn = 11; nn <= 25; nn++)
|
for (nn = 11; nn <= 25; nn++)
|
o = o | (getbit(i,nn)<<(nn+5));
|
o = o | (getbit(i,nn)<<(nn+5));
|
o = o | (p32 << 31);
|
o = o | (p32 << 31);
|
for (nn = 26; nn <= 31; nn++)
|
for (nn = 26; nn <= 31; nn++)
|
o = o | (getbit(i,nn)<<(nn+6));
|
o = o | (getbit(i,nn)<<(nn+6));
|
*/
|
*/
|
pg = checksum((int32_t*)&i)^p1^p2^p4^p8^p16^p32;
|
pg = checksum((int32_t*)&i)^p1^p2^p4^p8^p16^p32;
|
// o = i | (p32<<37)|(p16<<36)|(p8<<35)|(p4<<34)|(p2<<33)|(p1<<32) | (pg << 38);
|
// o = i | (p32<<37)|(p16<<36)|(p8<<35)|(p4<<34)|(p2<<33)|(p1<<32) | (pg << 38);
|
o = (p32<<5)|(p16<<4)|(p8<<3)|(p4<<2)|(p2<<1)|p1|(pg<<6);
|
o = (p32<<5)|(p16<<4)|(p8<<3)|(p4<<2)|(p2<<1)|p1|(pg<<6);
|
return o;
|
return o;
|
}
|
}
|
|
|
/*
|
/*
|
int PreProcessFile(char *nm)
|
int PreProcessFile(char *nm)
|
{
|
{
|
static char outname[1000];
|
static char outname[1000];
|
static char sysbuf[500];
|
static char sysbuf[500];
|
|
|
strcpy_s(outname, sizeof(outname), nm);
|
strcpy_s(outname, sizeof(outname), nm);
|
strcat_s(outname,sizeof(outname),".app.asm");
|
strcat_s(outname,sizeof(outname),".app.asm");
|
sprintf_s(sysbuf, sizeof(sysbuf), "app -V %s %s", nm, outname);
|
sprintf_s(sysbuf, sizeof(sysbuf), "app -V %s %s", nm, outname);
|
return system(sysbuf);
|
return system(sysbuf);
|
}
|
}
|
*/
|
*/
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
{
|
{
|
int nn,qq,kk;
|
int nn,qq,kk;
|
static char fname[500];
|
static char fname[500];
|
static char hexbuf[500];
|
static char hexbuf[500];
|
char *p;
|
char *p;
|
uint64_t lsa; // last start address
|
uint64_t lsa; // last start address
|
double bpi;
|
double bpi;
|
int64_t i64;
|
int64_t i64;
|
uint32_t u32;
|
uint32_t u32;
|
float nc2;
|
float nc2;
|
std::ifstream ifs;
|
std::ifstream ifs;
|
|
|
processOpt = 1;
|
processOpt = 1;
|
sections[bssseg].storebyte = 0;
|
sections[bssseg].storebyte = 0;
|
ofp = stdout;
|
ofp = stdout;
|
nn = processOptions(argc, argv);
|
nn = processOptions(argc, argv);
|
if (nn > argc-1) {
|
if (nn > argc-1) {
|
displayHelp();
|
displayHelp();
|
return 0;
|
return 0;
|
}
|
}
|
SymbolInit();
|
SymbolInit();
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
mfndx = 0;
|
mfndx = 0;
|
start_address = 0;
|
start_address = 0;
|
code_address = 0;
|
code_address = 0;
|
bss_address = 0;
|
bss_address = 0;
|
data_address = 0;
|
data_address = 0;
|
isInitializationData = 0;
|
isInitializationData = 0;
|
for (qq = 0; qq < 12; qq++)
|
for (qq = 0; qq < 12; qq++)
|
sections[qq].Clear();
|
sections[qq].Clear();
|
nmTable.Clear();
|
nmTable.Clear();
|
mofs.open("as64-master.asm");
|
mofs.open("as64-master.asm");
|
if (verbose) printf("Pass 1 - collect all input files.\r\n");
|
if (verbose) printf("Pass 1 - collect all input files.\r\n");
|
//PreProcessFile(fname);
|
//PreProcessFile(fname);
|
//strcat_s(fname,sizeof(fname),".app.asm");
|
//strcat_s(fname,sizeof(fname),".app.asm");
|
mname = std::string(fname);
|
mname = std::string(fname);
|
processFile(fname,0); // Pass 1, collect all include files
|
processFile(fname,0); // Pass 1, collect all include files
|
masterFileLength = mofs.tellp();
|
masterFileLength = mofs.tellp();
|
mofs.close();
|
mofs.close();
|
masterFile = new char[masterFileLength + 10000];
|
masterFile = new char[masterFileLength + 10000];
|
//if (debug) {
|
//if (debug) {
|
// FILE *fp;
|
// FILE *fp;
|
// fopen_s(&fp, "a64-master.asm", "w");
|
// fopen_s(&fp, "a64-master.asm", "w");
|
// if (fp) {
|
// if (fp) {
|
// fwrite(masterFile, 1, strlen(masterFile), fp);
|
// fwrite(masterFile, 1, strlen(masterFile), fp);
|
// fclose(fp);
|
// fclose(fp);
|
// }
|
// }
|
//}
|
//}
|
ZeroMemory(masterFile, masterFileLength + 10000);
|
ZeroMemory(masterFile, masterFileLength + 10000);
|
ifs.open("as64-master.asm");
|
ifs.open("as64-master.asm");
|
ifs.read(masterFile, masterFileLength + 10000);
|
ifs.read(masterFile, masterFileLength + 10000);
|
ifs.close();
|
ifs.close();
|
if (verbose) printf("Pass 2 - group and reorder segments\r\n");
|
if (verbose) printf("Pass 2 - group and reorder segments\r\n");
|
first_org = 1;
|
first_org = 1;
|
processSegments(); // Pass 2, group and order segments
|
processSegments(); // Pass 2, group and order segments
|
// ProcessSegments2();
|
// ProcessSegments2();
|
|
|
pass = 3;
|
pass = 3;
|
processMaster(); // Pass 3 collect up opcodes
|
processMaster(); // Pass 3 collect up opcodes
|
printf("Qsorting\r\n");
|
printf("Qsorting\r\n");
|
qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp);
|
qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp);
|
|
|
pass = 4;
|
pass = 4;
|
if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n");
|
if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n");
|
first_org = 1;
|
first_org = 1;
|
processMaster();
|
processMaster();
|
pass = 5;
|
pass = 5;
|
phasing_errors = 0;
|
phasing_errors = 0;
|
if (verbose) printf("Pass 5 - assemble code.\r\n");
|
if (verbose) printf("Pass 5 - assemble code.\r\n");
|
first_org = 1;
|
first_org = 1;
|
processMaster();
|
processMaster();
|
if (verbose) printf("Pass 6: phase errors: %d\r\n", phasing_errors);
|
if (verbose) printf("Pass 6: phase errors: %d\r\n", phasing_errors);
|
pass = 6;
|
pass = 6;
|
pe3 = pe2 = pe1 = 0;
|
pe3 = pe2 = pe1 = 0;
|
while (phasing_errors && pass < 40) {
|
while (phasing_errors && pass < 40) {
|
phasing_errors = 0;
|
phasing_errors = 0;
|
num_bytes = 0;
|
num_bytes = 0;
|
num_insns = 0;
|
num_insns = 0;
|
num_cinsns = 0;
|
num_cinsns = 0;
|
first_org = 1;
|
first_org = 1;
|
processMaster();
|
processMaster();
|
if (verbose) printf("Pass %d: phase errors: %d\r\n", pass, phasing_errors);
|
if (verbose) printf("Pass %d: phase errors: %d\r\n", pass, phasing_errors);
|
pass++;
|
pass++;
|
pe3 = pe2;
|
pe3 = pe2;
|
pe2 = pe1;
|
pe2 = pe1;
|
pe1 = phasing_errors;
|
pe1 = phasing_errors;
|
if (pe1==pe2 && pe2==pe3 && pe1==pe3) {
|
if (pe1==pe2 && pe2==pe3 && pe1==pe3) {
|
if (verbose)
|
if (verbose)
|
printf("Non converging phase errors\r\n");
|
printf("Non converging phase errors\r\n");
|
break;
|
break;
|
}
|
}
|
}
|
}
|
//processMaster();
|
//processMaster();
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output listing file.
|
// Output listing file.
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
ofp = (FILE *)NULL;
|
ofp = (FILE *)NULL;
|
if (listing) {
|
if (listing) {
|
if (verbose) printf("Generating listing file %s.\r\n", argv[nn]);
|
if (verbose) printf("Generating listing file %s.\r\n", argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".lst");
|
strcat_s(fname, sizeof(fname), ".lst");
|
fopen_s(&ofp, fname,"w");
|
fopen_s(&ofp, fname,"w");
|
if (!ofp)
|
if (!ofp)
|
printf("Can't open output file <%s>\r\n", fname);
|
printf("Can't open output file <%s>\r\n", fname);
|
bGen = 1;
|
bGen = 1;
|
}
|
}
|
processOpt = 2;
|
processOpt = 2;
|
bGenListing = true;
|
bGenListing = true;
|
processMaster();
|
processMaster();
|
bGenListing = false;
|
bGenListing = false;
|
DumpSymbols();
|
DumpSymbols();
|
DumphTable();
|
DumphTable();
|
fprintf(ofp, "\nnumber of bytes: %f\n", num_bytes);
|
fprintf(ofp, "\nnumber of bytes: %f\n", num_bytes);
|
fprintf(ofp, "number of instructions: %d\n", num_insns);
|
fprintf(ofp, "number of instructions: %d\n", num_insns);
|
fprintf(ofp, "number of compressed instructions: %d\n", num_cinsns);
|
fprintf(ofp, "number of compressed instructions: %d\n", num_cinsns);
|
bpi = (double)num_bytes/(double)num_insns;
|
bpi = (double)num_bytes/(double)num_insns;
|
fprintf(ofp, "%0.6f bytes (%d bits) per instruction\n", bpi, (int)(bpi*8));
|
fprintf(ofp, "%0.6f bytes (%d bits) per instruction\n", bpi, (int)(bpi*8));
|
nc2 = (float)num_cinsns * 2.0;
|
nc2 = (float)num_cinsns * 2.0;
|
fprintf(ofp, "Compression ratio: %f%%", (nc2 / (num_bytes + nc2)) * 100.0);
|
fprintf(ofp, "Compression ratio: %f%%", (nc2 / (num_bytes + nc2)) * 100.0);
|
|
|
/*
|
/*
|
chksum = 0;
|
chksum = 0;
|
for (nn = 0; nn < binndx; nn+=4) {
|
for (nn = 0; nn < binndx; nn+=4) {
|
chksum += binfile[nn] +
|
chksum += binfile[nn] +
|
(binfile[nn+1] << 8) +
|
(binfile[nn+1] << 8) +
|
(binfile[nn+2] << 16) +
|
(binfile[nn+2] << 16) +
|
(binfile[nn+3] << 24)
|
(binfile[nn+3] << 24)
|
;
|
;
|
}
|
}
|
|
|
fprintf(ofp, "\r\nChecksum: %08X\r\n", chksum);
|
fprintf(ofp, "\r\nChecksum: %08X\r\n", chksum);
|
*/
|
*/
|
if (listing)
|
if (listing)
|
fclose(ofp);
|
fclose(ofp);
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output binary file.
|
// Output binary file.
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (binary_out) {
|
if (binary_out) {
|
if (verbose) printf("Generating binary file.\r\n");
|
if (verbose) printf("Generating binary file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".bin");
|
strcat_s(fname, sizeof(fname), ".bin");
|
fopen_s(&ofp, fname,"wb");
|
fopen_s(&ofp, fname,"wb");
|
if (ofp) {
|
if (ofp) {
|
fwrite((void*)sections[0].bytes,sections[0].index,1,ofp);
|
fwrite((void*)sections[0].bytes,sections[0].index,1,ofp);
|
fwrite((void*)sections[1].bytes,sections[1].index,1,ofp);
|
fwrite((void*)sections[1].bytes,sections[1].index,1,ofp);
|
//fwrite((void*)sections[2].bytes,sections[2].index,1,ofp);
|
//fwrite((void*)sections[2].bytes,sections[2].index,1,ofp);
|
//fwrite(binfile,binndx,1,ofp);
|
//fwrite(binfile,binndx,1,ofp);
|
fclose(ofp);
|
fclose(ofp);
|
}
|
}
|
else
|
else
|
printf("Can't create .bin file.\r\n");
|
printf("Can't create .bin file.\r\n");
|
}
|
}
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output ELF file.
|
// Output ELF file.
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (elf_out) {
|
if (elf_out) {
|
if (verbose) printf("Generating ELF file.\r\n");
|
if (verbose) printf("Generating ELF file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
if (rel_out)
|
if (rel_out)
|
strcat_s(fname, sizeof(fname), ".rel");
|
strcat_s(fname, sizeof(fname), ".rel");
|
else
|
else
|
strcat_s(fname, sizeof(fname), ".elf");
|
strcat_s(fname, sizeof(fname), ".elf");
|
fopen_s(&ofp, fname,"wb");
|
fopen_s(&ofp, fname,"wb");
|
if (ofp) {
|
if (ofp) {
|
WriteELFFile(ofp);
|
WriteELFFile(ofp);
|
fclose(ofp);
|
fclose(ofp);
|
}
|
}
|
else
|
else
|
printf("Can't create .elf file.\r\n");
|
printf("Can't create .elf file.\r\n");
|
}
|
}
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output coe file
|
// Output coe file
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (coe_out) {
|
if (coe_out) {
|
if (verbose) printf("Generating COE file.\r\n");
|
if (verbose) printf("Generating COE file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".coe");
|
strcat_s(fname, sizeof(fname), ".coe");
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
fprintf(vfp, "memory_initialization_radix=16;\r\n");
|
fprintf(vfp, "memory_initialization_radix=16;\r\n");
|
fprintf(vfp, "memory_initialization_vector=\r\n");
|
fprintf(vfp, "memory_initialization_vector=\r\n");
|
for (kk = 0;kk < binndx; kk+=4) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
|
i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
|
fprintf(vfp, "%010I64X,\r\n", i64);
|
fprintf(vfp, "%010I64X,\r\n", i64);
|
}
|
}
|
fprintf(vfp,"000000;\r\n");
|
fprintf(vfp,"000000;\r\n");
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
}
|
}
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output Verilog memory declaration
|
// Output Verilog memory declaration
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (verilog_out) {
|
if (verilog_out) {
|
if (verbose) printf("Generating Verilog file.\r\n");
|
if (verbose) printf("Generating Verilog file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".ve0");
|
strcat_s(fname, sizeof(fname), ".ve0");
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
/*
|
/*
|
if (gCpu=='A') {
|
if (gCpu=='A') {
|
dsd9_VerilogOut(vfp);
|
dsd9_VerilogOut(vfp);
|
}
|
}
|
else
|
else
|
*/
|
*/
|
if (gCpu=='F' || gCpu=='G') {
|
if (gCpu=='F' || gCpu=='G') {
|
if (vebits==128) {
|
if (vebits==128) {
|
for (kk = 0; kk < binndx; kk+=16) {
|
for (kk = 0; kk < binndx; kk+=16) {
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
((((unsigned int)start_address+kk)/16)%16384), //checksum64((int64_t *)&binfile[kk]),
|
((((unsigned int)start_address+kk)/16)%16384), //checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
else if (vebits==64) {
|
else if (vebits==64) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
fprintf(vfp, "\trommem[%d] = 64'h%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem[%d] = 64'h%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
((((unsigned int)start_address+kk)/8)%16384), //checksum64((int64_t *)&binfile[kk]),
|
((((unsigned int)start_address+kk)/8)%16384), //checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
}
|
}
|
/*
|
/*
|
else if (gCpu=='G') {
|
else if (gCpu=='G') {
|
for (kk = 0; kk < binndx; kk+=32) {
|
for (kk = 0; kk < binndx; kk+=32) {
|
fprintf(vfp, "\trommem[%d] = 256'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
|
fprintf(vfp, "\trommem[%d] = 256'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
|
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
((((unsigned int)start_address+kk)/32)%16384), //checksum64((int64_t *)&binfile[kk]),
|
((((unsigned int)start_address+kk)/32)%16384), //checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+31], binfile[kk+30], binfile[kk+29], binfile[kk+28],
|
binfile[kk+31], binfile[kk+30], binfile[kk+29], binfile[kk+28],
|
binfile[kk+27], binfile[kk+26], binfile[kk+25], binfile[kk+24],
|
binfile[kk+27], binfile[kk+26], binfile[kk+25], binfile[kk+24],
|
binfile[kk+23], binfile[kk+22], binfile[kk+21], binfile[kk+20],
|
binfile[kk+23], binfile[kk+22], binfile[kk+21], binfile[kk+20],
|
binfile[kk+19], binfile[kk+18], binfile[kk+17], binfile[kk+16],
|
binfile[kk+19], binfile[kk+18], binfile[kk+17], binfile[kk+16],
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
*/
|
*/
|
else if (gCpu==64) {
|
else if (gCpu==64) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
fprintf(vfp, "\trommem0[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem0[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
else if (gCpu==5) {
|
else if (gCpu==5) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
i64 = (uint64_t)u32;
|
i64 = (uint64_t)u32;
|
fprintf(vfp, "\trommem[%d] = 32'h%08I64X;\n",
|
fprintf(vfp, "\trommem[%d] = 32'h%08I64X;\n",
|
(int)(((start_address+kk)/4)%32768), i64);
|
(int)(((start_address+kk)/4)%32768), i64);
|
}
|
}
|
}
|
}
|
else if (gCpu=='A') {
|
else if (gCpu=='A') {
|
for (kk = 0; kk < binndx; kk+=16) {
|
for (kk = 0; kk < binndx; kk+=16) {
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
(((0+kk)/16)%16384),
|
(((0+kk)/16)%16384),
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
if (kk != binndx)
|
if (kk != binndx)
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
(((0+kk)/16)%16384),
|
(((0+kk)/16)%16384),
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
else {
|
else {
|
for (kk = 0;kk < binndx; kk+=4) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
|
i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
|
i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
|
fprintf(vfp, "\trommem0[%d] = 39'h%010I64X;\n",
|
fprintf(vfp, "\trommem0[%d] = 39'h%010I64X;\n",
|
(int)(((0+kk)/4)%32768), i64);
|
(int)(((0+kk)/4)%32768), i64);
|
}
|
}
|
}
|
}
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
else
|
else
|
printf("Can't create .ver file.\r\n");
|
printf("Can't create .ver file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".ve1");
|
strcat_s(fname, sizeof(fname), ".ve1");
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
if (gCpu==64) {
|
if (gCpu==64) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
fprintf(vfp, "\trommem1[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem1[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+7]^0xAA, binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7]^0xAA, binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
else {
|
else {
|
for (kk = 0;kk < binndx; kk+=4) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
fprintf(vfp, "\trommem1[%d] = 32'h%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem1[%d] = 32'h%02X%02X%02X%02X;\n",
|
(((start_address+kk)/4)%32768), binfile[kk+3]^0xAA, binfile[kk+2]^0xAA, binfile[kk+1]^0xAA, binfile[kk]^0xAA);
|
(((start_address+kk)/4)%32768), binfile[kk+3]^0xAA, binfile[kk+2]^0xAA, binfile[kk+1]^0xAA, binfile[kk]^0xAA);
|
}
|
}
|
}
|
}
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
else
|
else
|
printf("Can't create .ver file.\r\n");
|
printf("Can't create .ver file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".ve2");
|
strcat_s(fname, sizeof(fname), ".ve2");
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
if (gCpu==64) {
|
if (gCpu==64) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
fprintf(vfp, "\trommem2[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem2[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
(((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
|
binfile[kk+7]^0x55, binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+7]^0x55, binfile[kk+6], binfile[kk+5], binfile[kk+4],
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
else {
|
else {
|
for (kk = 0;kk < binndx; kk+=4) {
|
for (kk = 0;kk < binndx; kk+=4) {
|
fprintf(vfp, "\trommem2[%d] = 32'h%02X%02X%02X%02X;\n",
|
fprintf(vfp, "\trommem2[%d] = 32'h%02X%02X%02X%02X;\n",
|
(((start_address+kk)/4)%32768), binfile[kk+3]^0x55, binfile[kk+2]^0x55, binfile[kk+1]^0x55, binfile[kk]^0x55);
|
(((start_address+kk)/4)%32768), binfile[kk+3]^0x55, binfile[kk+2]^0x55, binfile[kk+1]^0x55, binfile[kk]^0x55);
|
}
|
}
|
}
|
}
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
else
|
else
|
printf("Can't create .ver file.\r\n");
|
printf("Can't create .ver file.\r\n");
|
}
|
}
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output Verilog memory declaration
|
// Output Verilog memory declaration
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (verbose) printf("Generating Text file.\r\n");
|
if (verbose) printf("Generating Text file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
strcat_s(fname, sizeof(fname), ".txt");
|
strcat_s(fname, sizeof(fname), ".txt");
|
printf("fname:%s\r\n", fname);
|
printf("fname:%s\r\n", fname);
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
if (gCpu==64) {
|
if (gCpu==64) {
|
for (kk = 0; kk < binndx; kk+=4) {
|
for (kk = 0; kk < binndx; kk+=4) {
|
fprintf(vfp, "%06X,%02X%02X%02X%02X\n",
|
fprintf(vfp, "%06X,%02X%02X%02X%02X\n",
|
(((start_address+kk))),
|
(((start_address+kk))),
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
|
}
|
}
|
}
|
}
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
else
|
else
|
printf("Can't create .txt file.\r\n");
|
printf("Can't create .txt file.\r\n");
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// Output Intel hex file
|
// Output Intel hex file
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
if (verbose) printf("Generating Hex file.\r\n");
|
if (verbose) printf("Generating Hex file.\r\n");
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
strcpy_s(fname, sizeof(fname), argv[nn]);
|
p = strrchr(fname,'.');
|
p = strrchr(fname,'.');
|
if (p) {
|
if (p) {
|
*p = '\0';
|
*p = '\0';
|
}
|
}
|
lsa = 0;
|
lsa = 0;
|
strcat_s(fname, sizeof(fname), ".hex");
|
strcat_s(fname, sizeof(fname), ".hex");
|
printf("fname:%s\r\n", fname);
|
printf("fname:%s\r\n", fname);
|
fopen_s(&vfp, fname, "w");
|
fopen_s(&vfp, fname, "w");
|
if (vfp) {
|
if (vfp) {
|
if (gCpu==64||gCpu=='F'||gCpu=='G') {
|
if (gCpu==64||gCpu=='F'||gCpu=='G') {
|
for (kk = 0; kk < binndx; kk+=4) {
|
for (kk = 0; kk < binndx; kk+=4) {
|
if (lsa != (start_address + kk) >> 16) {
|
if (lsa != (start_address + kk) >> 16) {
|
sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
|
sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
|
IHChecksum(hexbuf, 2);
|
IHChecksum(hexbuf, 2);
|
fprintf(vfp, hexbuf);
|
fprintf(vfp, hexbuf);
|
lsa = (start_address+kk) >> 16;
|
lsa = (start_address+kk) >> 16;
|
}
|
}
|
sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X\n",
|
sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X\n",
|
4, (int)(start_address + kk) & 0xFFFF,
|
4, (int)(start_address + kk) & 0xFFFF,
|
binfile[kk], binfile[kk+1], binfile[kk+2], binfile[kk+3]
|
binfile[kk], binfile[kk+1], binfile[kk+2], binfile[kk+3]
|
);
|
);
|
IHChecksum(hexbuf, 4);
|
IHChecksum(hexbuf, 4);
|
fprintf(vfp, hexbuf);
|
fprintf(vfp, hexbuf);
|
}
|
}
|
}
|
}
|
else if (gCpu==4) {
|
else if (gCpu==4) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
for (kk = 0; kk < binndx; kk+=8) {
|
if (lsa != (start_address + kk) >> 16) {
|
if (lsa != (start_address + kk) >> 16) {
|
sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
|
sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
|
IHChecksum(hexbuf, 2);
|
IHChecksum(hexbuf, 2);
|
fprintf(vfp, hexbuf);
|
fprintf(vfp, hexbuf);
|
lsa = (start_address+kk) >> 16;
|
lsa = (start_address+kk) >> 16;
|
}
|
}
|
sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
8, (start_address + kk) & 0xFFFF,
|
8, (start_address + kk) & 0xFFFF,
|
binfile[kk], binfile[kk+1], binfile[kk+2],binfile[kk+3],
|
binfile[kk], binfile[kk+1], binfile[kk+2],binfile[kk+3],
|
binfile[kk+4],binfile[kk+5],binfile[kk+6],binfile[kk+7]
|
binfile[kk+4],binfile[kk+5],binfile[kk+6],binfile[kk+7]
|
);
|
);
|
IHChecksum(hexbuf, 8);
|
IHChecksum(hexbuf, 8);
|
fprintf(vfp, hexbuf);
|
fprintf(vfp, hexbuf);
|
}
|
}
|
}
|
}
|
fprintf(vfp, ":00000001FF\n%c",26); // end of file record
|
fprintf(vfp, ":00000001FF\n%c",26); // end of file record
|
fclose(vfp);
|
fclose(vfp);
|
}
|
}
|
else
|
else
|
printf("Can't create .hex file.\r\n");
|
printf("Can't create .hex file.\r\n");
|
delete[] masterFile;
|
delete[] masterFile;
|
return (0);
|
return (0);
|
}
|
}
|
|
|
bool IsNBit(int64_t val, int64_t n)
|
bool IsNBit(int64_t val, int64_t n)
|
{
|
{
|
int64_t low, high;
|
int64_t low, high;
|
|
|
low = -(1LL << (n - 1LL));
|
low = -(1LL << (n - 1LL));
|
high = (1LL << (n - 1LL));
|
high = (1LL << (n - 1LL));
|
return (val >= low && val < high);
|
return (val >= low && val < high);
|
}
|
}
|
|
|