// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2017-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"
|
|
|
static void ProcessEOL(int opt);
|
static void ProcessEOL(int opt);
|
extern void process_message();
|
extern void process_message();
|
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc);
|
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc);
|
|
|
extern char *pif1;
|
extern char *pif1;
|
extern int first_rodata;
|
extern int first_rodata;
|
extern int first_data;
|
extern int first_data;
|
extern int first_bss;
|
extern int first_bss;
|
extern int htable[100000];
|
|
extern int htblcnt[100000];
|
|
extern int htblmax;
|
extern int htblmax;
|
extern int pass;
|
extern int pass;
|
extern int num_cinsns;
|
extern int num_cinsns;
|
|
|
static int64_t ca;
|
static int64_t ca;
|
|
|
extern int use_gp;
|
extern int use_gp;
|
|
|
static int regSP = 31;
|
static int regSP = 31;
|
static int regFP = 30;
|
static int regFP = 30;
|
static int regLR = 29;
|
static int regLR = 29;
|
static int regXL = 28;
|
static int regXL = 28;
|
static int regGP = 27;
|
static int regGP = 27;
|
static int regTP = 26;
|
static int regTP = 26;
|
static int regCB = 23;
|
static int regCB = 23;
|
static int regCnst;
|
static int regCnst;
|
|
|
#define OPT64 0
|
#define OPT64 0
|
#define OPTX32 1
|
#define OPTX32 1
|
#define OPTLUI0 0
|
#define OPTLUI0 0
|
#define LB16 -31653LL
|
#define LB16 -31653LL
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void error(char *msg)
|
static void error(char *msg)
|
{
|
{
|
printf("%s. (%d)\n", msg, /*mname.c_str(), */lineno);
|
printf("%s. (%d)\n", msg, /*mname.c_str(), */lineno);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Return the register number or -1 if not a register.
|
// Return the register number or -1 if not a register.
|
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
|
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
//static int getRegisterX()
|
//static int getRegisterX()
|
//{
|
//{
|
// int reg;
|
// int reg;
|
//
|
//
|
// while(isspace(*inptr)) inptr++;
|
// while(isspace(*inptr)) inptr++;
|
// if (*inptr == '$')
|
// if (*inptr == '$')
|
// inptr++;
|
// inptr++;
|
// switch(*inptr) {
|
// switch(*inptr) {
|
// case 'r': case 'R':
|
// case 'r': case 'R':
|
// if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 29;
|
// return 29;
|
// }
|
// }
|
// if (isdigit(inptr[1])) {
|
// if (isdigit(inptr[1])) {
|
// reg = inptr[1]-'0';
|
// reg = inptr[1]-'0';
|
// if (isdigit(inptr[2])) {
|
// if (isdigit(inptr[2])) {
|
// reg = 10 * reg + (inptr[2]-'0');
|
// reg = 10 * reg + (inptr[2]-'0');
|
// if (isdigit(inptr[3])) {
|
// if (isdigit(inptr[3])) {
|
// reg = 10 * reg + (inptr[3]-'0');
|
// reg = 10 * reg + (inptr[3]-'0');
|
// if (isIdentChar(inptr[4]))
|
// if (isIdentChar(inptr[4]))
|
// return -1;
|
// return -1;
|
// inptr += 4;
|
// inptr += 4;
|
// NextToken();
|
// NextToken();
|
// return reg;
|
// return reg;
|
// }
|
// }
|
// else if (isIdentChar(inptr[3]))
|
// else if (isIdentChar(inptr[3]))
|
// return -1;
|
// return -1;
|
// else {
|
// else {
|
// inptr += 3;
|
// inptr += 3;
|
// NextToken();
|
// NextToken();
|
// return reg;
|
// return reg;
|
// }
|
// }
|
// }
|
// }
|
// else if (isIdentChar(inptr[2]))
|
// else if (isIdentChar(inptr[2]))
|
// return -1;
|
// return -1;
|
// else {
|
// else {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return reg;
|
// return reg;
|
// }
|
// }
|
// }
|
// }
|
// else return -1;
|
// else return -1;
|
// case 'a': case 'A':
|
// case 'a': case 'A':
|
// if (isdigit(inptr[1])) {
|
// if (isdigit(inptr[1])) {
|
// reg = inptr[1]-'0' + 18;
|
// reg = inptr[1]-'0' + 18;
|
// if (isIdentChar(inptr[2]))
|
// if (isIdentChar(inptr[2]))
|
// return -1;
|
// return -1;
|
// else {
|
// else {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return reg;
|
// return reg;
|
// }
|
// }
|
// }
|
// }
|
// else return -1;
|
// else return -1;
|
// case 'b': case 'B':
|
// case 'b': case 'B':
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 30;
|
// return 30;
|
// }
|
// }
|
// break;
|
// break;
|
// case 'f': case 'F':
|
// case 'f': case 'F':
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 2;
|
// return 2;
|
// }
|
// }
|
// break;
|
// break;
|
// case 'g': case 'G':
|
// case 'g': case 'G':
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 26;
|
// return 26;
|
// }
|
// }
|
// break;
|
// break;
|
// case 'p': case 'P':
|
// case 'p': case 'P':
|
// if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 31;
|
// return 31;
|
// }
|
// }
|
// break;
|
// break;
|
// case 's': case 'S':
|
// case 's': case 'S':
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 31;
|
// return 31;
|
// }
|
// }
|
// break;
|
// break;
|
// case 't': case 'T':
|
// case 't': case 'T':
|
// if (isdigit(inptr[1])) {
|
// if (isdigit(inptr[1])) {
|
// reg = inptr[1]-'0' + 26;
|
// reg = inptr[1]-'0' + 26;
|
// if (isIdentChar(inptr[2]))
|
// if (isIdentChar(inptr[2]))
|
// return -1;
|
// return -1;
|
// else {
|
// else {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return reg;
|
// return reg;
|
// }
|
// }
|
// }
|
// }
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 15;
|
// return 15;
|
// }
|
// }
|
// /*
|
// /*
|
// if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 24;
|
// return 24;
|
// }
|
// }
|
// */
|
// */
|
// break;
|
// break;
|
// // lr
|
// // lr
|
// case 'l': case 'L':
|
// case 'l': case 'L':
|
// if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
// if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
// inptr += 2;
|
// inptr += 2;
|
// NextToken();
|
// NextToken();
|
// return 29;
|
// return 29;
|
// }
|
// }
|
// break;
|
// break;
|
// // xlr
|
// // xlr
|
// case 'x': case 'X':
|
// case 'x': case 'X':
|
// if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
|
// if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
|
// !isIdentChar(inptr[3])) {
|
// !isIdentChar(inptr[3])) {
|
// inptr += 3;
|
// inptr += 3;
|
// NextToken();
|
// NextToken();
|
// return 28;
|
// return 28;
|
// }
|
// }
|
// break;
|
// break;
|
// default:
|
// default:
|
// return -1;
|
// return -1;
|
// }
|
// }
|
// return -1;
|
// return -1;
|
//}
|
//}
|
static int getRegisterX()
|
static int getRegisterX()
|
{
|
{
|
int reg;
|
int reg;
|
|
|
while(isspace(*inptr)) inptr++;
|
while(isspace(*inptr)) inptr++;
|
if (*inptr == '$')
|
if (*inptr == '$')
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case 'r': case 'R':
|
case 'r': case 'R':
|
if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return regLR;
|
return regLR;
|
}
|
}
|
if (isdigit(inptr[1])) {
|
if (isdigit(inptr[1])) {
|
reg = inptr[1]-'0';
|
reg = inptr[1]-'0';
|
if (isdigit(inptr[2])) {
|
if (isdigit(inptr[2])) {
|
reg = 10 * reg + (inptr[2]-'0');
|
reg = 10 * reg + (inptr[2]-'0');
|
if (isdigit(inptr[3])) {
|
if (isdigit(inptr[3])) {
|
reg = 10 * reg + (inptr[3]-'0');
|
reg = 10 * reg + (inptr[3]-'0');
|
if (isIdentChar(inptr[4]))
|
if (isIdentChar(inptr[4]))
|
return -1;
|
return -1;
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
else if (isIdentChar(inptr[3]))
|
else if (isIdentChar(inptr[3]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
else if (isIdentChar(inptr[2]))
|
else if (isIdentChar(inptr[2]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
else return -1;
|
else return -1;
|
case 'a': case 'A':
|
case 'a': case 'A':
|
if (isdigit(inptr[1])) {
|
if (isdigit(inptr[1])) {
|
reg = inptr[1]-'0' + 18;
|
reg = inptr[1]-'0' + 18;
|
if (isIdentChar(inptr[2]))
|
if (isIdentChar(inptr[2]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
else return -1;
|
else return -1;
|
case 'f': case 'F':
|
case 'f': case 'F':
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return regFP;
|
return regFP;
|
}
|
}
|
break;
|
break;
|
case 'g': case 'G':
|
case 'g': case 'G':
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return regGP;
|
return regGP;
|
}
|
}
|
break;
|
break;
|
case 'p': case 'P':
|
case 'p': case 'P':
|
if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 31;
|
return 31;
|
}
|
}
|
break;
|
break;
|
case 's': case 'S':
|
case 's': case 'S':
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return (regSP);
|
return (regSP);
|
}
|
}
|
break;
|
break;
|
case 't': case 'T':
|
case 't': case 'T':
|
if (isdigit(inptr[1])) {
|
if (isdigit(inptr[1])) {
|
reg = inptr[1]-'0' + 5;
|
reg = inptr[1]-'0' + 5;
|
if (isdigit(inptr[2])) {
|
if (isdigit(inptr[2])) {
|
reg = 10 * reg + (inptr[2]-'0');
|
reg = 10 * reg + (inptr[2]-'0');
|
if (isdigit(inptr[3])) {
|
if (isdigit(inptr[3])) {
|
reg = 10 * reg + (inptr[3]-'0');
|
reg = 10 * reg + (inptr[3]-'0');
|
if (isIdentChar(inptr[4]))
|
if (isIdentChar(inptr[4]))
|
return -1;
|
return -1;
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
else if (isIdentChar(inptr[3]))
|
else if (isIdentChar(inptr[3]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
if (isIdentChar(inptr[2]))
|
if (isIdentChar(inptr[2]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return (reg);
|
return (reg);
|
}
|
}
|
}
|
}
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return (regTP);
|
return (regTP);
|
}
|
}
|
/*
|
/*
|
if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 24;
|
return 24;
|
}
|
}
|
*/
|
*/
|
break;
|
break;
|
// lr
|
// lr
|
case 'l': case 'L':
|
case 'l': case 'L':
|
if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return (regLR);
|
return (regLR);
|
}
|
}
|
break;
|
break;
|
// xlr
|
// xlr
|
case 'x': case 'X':
|
case 'x': case 'X':
|
if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
|
if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return (regXL);
|
return (regXL);
|
}
|
}
|
break;
|
break;
|
case 'v': case 'V':
|
case 'v': case 'V':
|
if (isdigit(inptr[1])) {
|
if (isdigit(inptr[1])) {
|
reg = inptr[1]-'0' + 1;
|
reg = inptr[1]-'0' + 1;
|
if (isIdentChar(inptr[2]))
|
if (isIdentChar(inptr[2]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return (reg);
|
return (reg);
|
}
|
}
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
return -1;
|
return -1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
static int isdelim(char ch)
|
static int isdelim(char ch)
|
{
|
{
|
return ch==',' || ch=='[' || ch=='(' || ch==']' || ch==')' || ch=='.';
|
return ch==',' || ch=='[' || ch=='(' || ch==']' || ch==')' || ch=='.';
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Return the register number or -1 if not a register.
|
// Return the register number or -1 if not a register.
|
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
|
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static int getVecRegister()
|
static int getVecRegister()
|
{
|
{
|
int reg;
|
int reg;
|
|
|
while(isspace(*inptr)) inptr++;
|
while(isspace(*inptr)) inptr++;
|
if (*inptr=='$')
|
if (*inptr=='$')
|
inptr++;
|
inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
case 'v': case 'V':
|
case 'v': case 'V':
|
if (isdigit(inptr[1])) {
|
if (isdigit(inptr[1])) {
|
reg = inptr[1]-'0';
|
reg = inptr[1]-'0';
|
if (isdigit(inptr[2])) {
|
if (isdigit(inptr[2])) {
|
reg = 10 * reg + (inptr[2]-'0');
|
reg = 10 * reg + (inptr[2]-'0');
|
if (isdigit(inptr[3])) {
|
if (isdigit(inptr[3])) {
|
reg = 10 * reg + (inptr[3]-'0');
|
reg = 10 * reg + (inptr[3]-'0');
|
if (isIdentChar(inptr[4]))
|
if (isIdentChar(inptr[4]))
|
return -1;
|
return -1;
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
else if (isIdentChar(inptr[3]))
|
else if (isIdentChar(inptr[3]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
else if (isIdentChar(inptr[2]))
|
else if (isIdentChar(inptr[2]))
|
return -1;
|
return -1;
|
else {
|
else {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return reg;
|
return reg;
|
}
|
}
|
}
|
}
|
else if (inptr[1]=='l' || inptr[1]=='L') {
|
else if (inptr[1]=='l' || inptr[1]=='L') {
|
if (!isIdentChar(inptr[2])) {
|
if (!isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x2F;
|
return 0x2F;
|
}
|
}
|
}
|
}
|
else if (inptr[1]=='m' || inptr[1]=='M') {
|
else if (inptr[1]=='m' || inptr[1]=='M') {
|
if (isdigit(inptr[2])) {
|
if (isdigit(inptr[2])) {
|
if (inptr[2] >= '0' && inptr[2] <= '7') {
|
if (inptr[2] >= '0' && inptr[2] <= '7') {
|
if (!isIdentChar(inptr[3])) {
|
if (!isIdentChar(inptr[3])) {
|
reg = 0x20 | (inptr[2]-'0');
|
reg = 0x20 | (inptr[2]-'0');
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return (reg);
|
return (reg);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Get the friendly name of a special purpose register.
|
// Get the friendly name of a special purpose register.
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static int DSD7_getSprRegister()
|
static int DSD7_getSprRegister()
|
{
|
{
|
int reg = -1;
|
int reg = -1;
|
int pr;
|
int pr;
|
|
|
while(isspace(*inptr)) inptr++;
|
while(isspace(*inptr)) inptr++;
|
// reg = getCodeareg();
|
// reg = getCodeareg();
|
if (reg >= 0) {
|
if (reg >= 0) {
|
reg |= 0x10;
|
reg |= 0x10;
|
return reg;
|
return reg;
|
}
|
}
|
if (inptr[0]=='p' || inptr[0]=='P') {
|
if (inptr[0]=='p' || inptr[0]=='P') {
|
if (isdigit(inptr[1]) && isdigit(inptr[2])) {
|
if (isdigit(inptr[1]) && isdigit(inptr[2])) {
|
pr = ((inptr[1]-'0' * 10) + (inptr[2]-'0'));
|
pr = ((inptr[1]-'0' * 10) + (inptr[2]-'0'));
|
if (!isIdentChar(inptr[3])) {
|
if (!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return pr | 0x40;
|
return pr | 0x40;
|
}
|
}
|
}
|
}
|
else if (isdigit(inptr[1])) {
|
else if (isdigit(inptr[1])) {
|
pr = (inptr[1]-'0');
|
pr = (inptr[1]-'0');
|
if (!isIdentChar(inptr[2])) {
|
if (!isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return pr | 0x40;
|
return pr | 0x40;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
while(isspace(*inptr)) inptr++;
|
while(isspace(*inptr)) inptr++;
|
switch(*inptr) {
|
switch(*inptr) {
|
|
|
case '0':
|
case '0':
|
case '1':
|
case '1':
|
case '2':
|
case '2':
|
case '3':
|
case '3':
|
case '4':
|
case '4':
|
case '5':
|
case '5':
|
case '6':
|
case '6':
|
case '7':
|
case '7':
|
case '8':
|
case '8':
|
case '9':
|
case '9':
|
NextToken();
|
NextToken();
|
NextToken();
|
NextToken();
|
return (int)ival.low & 0xFFF;
|
return (int)ival.low & 0xFFF;
|
|
|
// arg1
|
// arg1
|
case 'a': case 'A':
|
case 'a': case 'A':
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='g' || inptr[2]=='G') &&
|
(inptr[2]=='g' || inptr[2]=='G') &&
|
(inptr[3]=='1' || inptr[3]=='1') &&
|
(inptr[3]=='1' || inptr[3]=='1') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 58;
|
return 58;
|
}
|
}
|
break;
|
break;
|
// bear
|
// bear
|
case 'b': case 'B':
|
case 'b': case 'B':
|
if ((inptr[1]=='e' || inptr[1]=='E') &&
|
if ((inptr[1]=='e' || inptr[1]=='E') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='r' || inptr[3]=='R') &&
|
(inptr[3]=='r' || inptr[3]=='R') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 11;
|
return 11;
|
}
|
}
|
break;
|
break;
|
// cas clk cr0 cr3 cs CPL
|
// cas clk cr0 cr3 cs CPL
|
case 'c': case 'C':
|
case 'c': case 'C':
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
(inptr[2]=='s' || inptr[2]=='S') &&
|
(inptr[2]=='s' || inptr[2]=='S') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 44;
|
return 44;
|
}
|
}
|
if ((inptr[1]=='l' || inptr[1]=='L') &&
|
if ((inptr[1]=='l' || inptr[1]=='L') &&
|
(inptr[2]=='k' || inptr[2]=='K') &&
|
(inptr[2]=='k' || inptr[2]=='K') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 0x06;
|
return 0x06;
|
}
|
}
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='0') &&
|
(inptr[2]=='0') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 0x00;
|
return 0x00;
|
}
|
}
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='3') &&
|
(inptr[2]=='3') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 0x03;
|
return 0x03;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2F;
|
return 0x2F;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x27;
|
return 0x27;
|
}
|
}
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
(inptr[2]=='l' || inptr[2]=='L') &&
|
(inptr[2]=='l' || inptr[2]=='L') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 42;
|
return 42;
|
}
|
}
|
break;
|
break;
|
|
|
// dbad0 dbad1 dbctrl dpc dsp ds
|
// dbad0 dbad1 dbctrl dpc dsp ds
|
case 'd': case 'D':
|
case 'd': case 'D':
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[4]=='0' || inptr[4]=='0') &&
|
(inptr[4]=='0' || inptr[4]=='0') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 50;
|
return 50;
|
}
|
}
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[4]=='1' || inptr[4]=='1') &&
|
(inptr[4]=='1' || inptr[4]=='1') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 51;
|
return 51;
|
}
|
}
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[4]=='2' || inptr[4]=='2') &&
|
(inptr[4]=='2' || inptr[4]=='2') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 52;
|
return 52;
|
}
|
}
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[4]=='3' || inptr[4]=='3') &&
|
(inptr[4]=='3' || inptr[4]=='3') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 53;
|
return 53;
|
}
|
}
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[3]=='t' || inptr[3]=='T') &&
|
(inptr[3]=='t' || inptr[3]=='T') &&
|
(inptr[4]=='r' || inptr[4]=='R') &&
|
(inptr[4]=='r' || inptr[4]=='R') &&
|
(inptr[5]=='l' || inptr[5]=='L') &&
|
(inptr[5]=='l' || inptr[5]=='L') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 54;
|
return 54;
|
}
|
}
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 7;
|
return 7;
|
}
|
}
|
if (
|
if (
|
(inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
(inptr[3]=='c' || inptr[3]=='C') &&
|
(inptr[3]=='c' || inptr[3]=='C') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 7;
|
return 7;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 16;
|
return 16;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x29;
|
return 0x29;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x21;
|
return 0x21;
|
}
|
}
|
break;
|
break;
|
|
|
// ea epc esp es
|
// ea epc esp es
|
case 'e': case 'E':
|
case 'e': case 'E':
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 40;
|
return 40;
|
}
|
}
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 9;
|
return 9;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 17;
|
return 17;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2A;
|
return 0x2A;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x22;
|
return 0x22;
|
}
|
}
|
break;
|
break;
|
|
|
// fault_pc fs
|
// fault_pc fs
|
case 'f': case 'F':
|
case 'f': case 'F':
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
(inptr[2]=='u' || inptr[2]=='U') &&
|
(inptr[2]=='u' || inptr[2]=='U') &&
|
(inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='t' || inptr[4]=='T') &&
|
(inptr[4]=='t' || inptr[4]=='T') &&
|
(inptr[5]=='_' || inptr[5]=='_') &&
|
(inptr[5]=='_' || inptr[5]=='_') &&
|
(inptr[6]=='p' || inptr[6]=='P') &&
|
(inptr[6]=='p' || inptr[6]=='P') &&
|
(inptr[7]=='c' || inptr[7]=='C') &&
|
(inptr[7]=='c' || inptr[7]=='C') &&
|
!isIdentChar(inptr[8])) {
|
!isIdentChar(inptr[8])) {
|
inptr += 8;
|
inptr += 8;
|
NextToken();
|
NextToken();
|
return 0x08;
|
return 0x08;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2B;
|
return 0x2B;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x23;
|
return 0x23;
|
}
|
}
|
break;
|
break;
|
|
|
// gs GDT
|
// gs GDT
|
case 'g': case 'G':
|
case 'g': case 'G':
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2C;
|
return 0x2C;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x24;
|
return 0x24;
|
}
|
}
|
if ((inptr[1]=='d' || inptr[1]=='D') &&
|
if ((inptr[1]=='d' || inptr[1]=='D') &&
|
(inptr[2]=='t' || inptr[2]=='T') &&
|
(inptr[2]=='t' || inptr[2]=='T') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 41;
|
return 41;
|
}
|
}
|
break;
|
break;
|
|
|
// history
|
// history
|
case 'h': case 'H':
|
case 'h': case 'H':
|
if ((inptr[1]=='i' || inptr[1]=='I') &&
|
if ((inptr[1]=='i' || inptr[1]=='I') &&
|
(inptr[2]=='s' || inptr[2]=='S') &&
|
(inptr[2]=='s' || inptr[2]=='S') &&
|
(inptr[3]=='t' || inptr[3]=='T') &&
|
(inptr[3]=='t' || inptr[3]=='T') &&
|
(inptr[4]=='o' || inptr[4]=='O') &&
|
(inptr[4]=='o' || inptr[4]=='O') &&
|
(inptr[5]=='r' || inptr[5]=='R') &&
|
(inptr[5]=='r' || inptr[5]=='R') &&
|
(inptr[6]=='y' || inptr[6]=='Y') &&
|
(inptr[6]=='y' || inptr[6]=='Y') &&
|
!isIdentChar(inptr[7])) {
|
!isIdentChar(inptr[7])) {
|
inptr += 7;
|
inptr += 7;
|
NextToken();
|
NextToken();
|
return 0x0D;
|
return 0x0D;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2D;
|
return 0x2D;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x25;
|
return 0x25;
|
}
|
}
|
break;
|
break;
|
|
|
// ipc isp ivno
|
// ipc isp ivno
|
case 'i': case 'I':
|
case 'i': case 'I':
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 8;
|
return 8;
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
(inptr[2]=='p' || inptr[2]=='P') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 15;
|
return 15;
|
}
|
}
|
if ((inptr[1]=='v' || inptr[1]=='V') &&
|
if ((inptr[1]=='v' || inptr[1]=='V') &&
|
(inptr[2]=='n' || inptr[2]=='N') &&
|
(inptr[2]=='n' || inptr[2]=='N') &&
|
(inptr[3]=='o' || inptr[3]=='O') &&
|
(inptr[3]=='o' || inptr[3]=='O') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 0x0C;
|
return 0x0C;
|
}
|
}
|
break;
|
break;
|
|
|
|
|
// LC LDT
|
// LC LDT
|
case 'l': case 'L':
|
case 'l': case 'L':
|
if ((inptr[1]=='c' || inptr[1]=='C') &&
|
if ((inptr[1]=='c' || inptr[1]=='C') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x33;
|
return 0x33;
|
}
|
}
|
if ((inptr[1]=='d' || inptr[1]=='D') &&
|
if ((inptr[1]=='d' || inptr[1]=='D') &&
|
(inptr[2]=='t' || inptr[2]=='T') &&
|
(inptr[2]=='t' || inptr[2]=='T') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 40;
|
return 40;
|
}
|
}
|
break;
|
break;
|
|
|
// pregs
|
// pregs
|
case 'p': case 'P':
|
case 'p': case 'P':
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='e' || inptr[2]=='E') &&
|
(inptr[2]=='e' || inptr[2]=='E') &&
|
(inptr[3]=='g' || inptr[3]=='G') &&
|
(inptr[3]=='g' || inptr[3]=='G') &&
|
(inptr[4]=='s' || inptr[4]=='S') &&
|
(inptr[4]=='s' || inptr[4]=='S') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 52;
|
return 52;
|
}
|
}
|
break;
|
break;
|
|
|
// rand
|
// rand
|
case 'r': case 'R':
|
case 'r': case 'R':
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
(inptr[2]=='n' || inptr[2]=='N') &&
|
(inptr[2]=='n' || inptr[2]=='N') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
(inptr[3]=='d' || inptr[3]=='D') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 0x12;
|
return 0x12;
|
}
|
}
|
break;
|
break;
|
// ss_ll srand1 srand2 ss segsw segbase seglmt segacr
|
// ss_ll srand1 srand2 ss segsw segbase seglmt segacr
|
case 's': case 'S':
|
case 's': case 'S':
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
(inptr[2]=='_' || inptr[2]=='_') &&
|
(inptr[2]=='_' || inptr[2]=='_') &&
|
(inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='l' || inptr[4]=='L') &&
|
(inptr[4]=='l' || inptr[4]=='L') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 0x1A;
|
return 0x1A;
|
}
|
}
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='n' || inptr[3]=='N') &&
|
(inptr[3]=='n' || inptr[3]=='N') &&
|
(inptr[4]=='d' || inptr[4]=='D') &&
|
(inptr[4]=='d' || inptr[4]=='D') &&
|
(inptr[5]=='1') &&
|
(inptr[5]=='1') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x10;
|
return 0x10;
|
}
|
}
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
if ((inptr[1]=='r' || inptr[1]=='R') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[2]=='a' || inptr[2]=='A') &&
|
(inptr[3]=='n' || inptr[3]=='N') &&
|
(inptr[3]=='n' || inptr[3]=='N') &&
|
(inptr[4]=='d' || inptr[4]=='D') &&
|
(inptr[4]=='d' || inptr[4]=='D') &&
|
(inptr[5]=='2') &&
|
(inptr[5]=='2') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x11;
|
return 0x11;
|
}
|
}
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
if ((inptr[1]=='p' || inptr[1]=='P') &&
|
(inptr[2]=='r' || inptr[2]=='R') &&
|
(inptr[2]=='r' || inptr[2]=='R') &&
|
isdigit(inptr[3]) && isdigit(inptr[4]) &&
|
isdigit(inptr[3]) && isdigit(inptr[4]) &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return (inptr[3]-'0')*10 + (inptr[4]-'0');
|
return (inptr[3]-'0')*10 + (inptr[4]-'0');
|
}
|
}
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x2E;
|
return 0x2E;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x26;
|
return 0x26;
|
}
|
}
|
// segxxx
|
// segxxx
|
if ((inptr[1]=='e' || inptr[1]=='E') &&
|
if ((inptr[1]=='e' || inptr[1]=='E') &&
|
(inptr[2]=='g' || inptr[2]=='G')) {
|
(inptr[2]=='g' || inptr[2]=='G')) {
|
// segsw
|
// segsw
|
if ((inptr[3]=='s' || inptr[3]=='S') &&
|
if ((inptr[3]=='s' || inptr[3]=='S') &&
|
(inptr[4]=='w' || inptr[4]=='W') &&
|
(inptr[4]=='w' || inptr[4]=='W') &&
|
!isIdentChar(inptr[5])) {
|
!isIdentChar(inptr[5])) {
|
inptr += 5;
|
inptr += 5;
|
NextToken();
|
NextToken();
|
return 43;
|
return 43;
|
}
|
}
|
// segbase
|
// segbase
|
if ((inptr[3]=='b' || inptr[3]=='B') &&
|
if ((inptr[3]=='b' || inptr[3]=='B') &&
|
(inptr[4]=='a' || inptr[4]=='A') &&
|
(inptr[4]=='a' || inptr[4]=='A') &&
|
(inptr[5]=='s' || inptr[5]=='S') &&
|
(inptr[5]=='s' || inptr[5]=='S') &&
|
(inptr[6]=='e' || inptr[6]=='E') &&
|
(inptr[6]=='e' || inptr[6]=='E') &&
|
!isIdentChar(inptr[7])) {
|
!isIdentChar(inptr[7])) {
|
inptr += 7;
|
inptr += 7;
|
NextToken();
|
NextToken();
|
return 44;
|
return 44;
|
}
|
}
|
// seglmt
|
// seglmt
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 45;
|
return 45;
|
}
|
}
|
// segacr
|
// segacr
|
if ((inptr[3]=='a' || inptr[3]=='A') &&
|
if ((inptr[3]=='a' || inptr[3]=='A') &&
|
(inptr[4]=='c' || inptr[4]=='C') &&
|
(inptr[4]=='c' || inptr[4]=='C') &&
|
(inptr[5]=='r' || inptr[5]=='R') &&
|
(inptr[5]=='r' || inptr[5]=='R') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 47;
|
return 47;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
|
// tag tick
|
// tag tick
|
case 't': case 'T':
|
case 't': case 'T':
|
if ((inptr[1]=='i' || inptr[1]=='I') &&
|
if ((inptr[1]=='i' || inptr[1]=='I') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[2]=='c' || inptr[2]=='C') &&
|
(inptr[3]=='k' || inptr[3]=='K') &&
|
(inptr[3]=='k' || inptr[3]=='K') &&
|
!isIdentChar(inptr[4])) {
|
!isIdentChar(inptr[4])) {
|
inptr += 4;
|
inptr += 4;
|
NextToken();
|
NextToken();
|
return 0x32;
|
return 0x32;
|
}
|
}
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
if ((inptr[1]=='a' || inptr[1]=='A') &&
|
(inptr[2]=='g' || inptr[2]=='G') &&
|
(inptr[2]=='g' || inptr[2]=='G') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 41;
|
return 41;
|
}
|
}
|
break;
|
break;
|
|
|
// vbr
|
// vbr
|
case 'v': case 'V':
|
case 'v': case 'V':
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
if ((inptr[1]=='b' || inptr[1]=='B') &&
|
(inptr[2]=='r' || inptr[2]=='R') &&
|
(inptr[2]=='r' || inptr[2]=='R') &&
|
!isIdentChar(inptr[3])) {
|
!isIdentChar(inptr[3])) {
|
inptr += 3;
|
inptr += 3;
|
NextToken();
|
NextToken();
|
return 10;
|
return 10;
|
}
|
}
|
break;
|
break;
|
case 'z': case 'Z':
|
case 'z': case 'Z':
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
if ((inptr[1]=='s' || inptr[1]=='S') &&
|
!isIdentChar(inptr[2])) {
|
!isIdentChar(inptr[2])) {
|
if (inptr[2]=='.') {
|
if (inptr[2]=='.') {
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
if ((inptr[3]=='l' || inptr[3]=='L') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[4]=='m' || inptr[4]=='M') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
(inptr[5]=='t' || inptr[5]=='T') &&
|
!isIdentChar(inptr[6])) {
|
!isIdentChar(inptr[6])) {
|
inptr += 6;
|
inptr += 6;
|
NextToken();
|
NextToken();
|
return 0x28;
|
return 0x28;
|
}
|
}
|
}
|
}
|
inptr += 2;
|
inptr += 2;
|
NextToken();
|
NextToken();
|
return 0x20;
|
return 0x20;
|
}
|
}
|
break;
|
break;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
// Detect if a register can be part of a compressed instruction
|
// Detect if a register can be part of a compressed instruction
|
int CmpReg(int reg)
|
int CmpReg(int reg)
|
{
|
{
|
switch(reg) {
|
switch(reg) {
|
case 1: return(0);
|
case 1: return(0);
|
case 3: return(1);
|
case 3: return(1);
|
case 4: return(2);
|
case 4: return(2);
|
case 11: return(3);
|
case 11: return(3);
|
case 12: return(4);
|
case 12: return(4);
|
case 18: return(5);
|
case 18: return(5);
|
case 19: return(6);
|
case 19: return(6);
|
case 20: return(7);
|
case 20: return(7);
|
default:
|
default:
|
return(-1);
|
return(-1);
|
}
|
}
|
}
|
}
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// Process the size specifier for a FP instruction.
|
// Process the size specifier for a FP instruction.
|
// h: half (16 bit)
|
// h: half (16 bit)
|
// s: single (32 bit)
|
// s: single (32 bit)
|
// d: double (64 bit)
|
// d: double (64 bit)
|
// t: triple (96 bit)
|
// t: triple (96 bit)
|
// q: quad (128 bit)
|
// q: quad (128 bit)
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static int GetFPSize()
|
static int GetFPSize()
|
{
|
{
|
int sz;
|
int sz;
|
|
|
sz = 'd';
|
sz = 'd';
|
if (*inptr=='.') {
|
if (*inptr=='.') {
|
inptr++;
|
inptr++;
|
if (strchr("hsdtqHSDTQ",*inptr)) {
|
if (strchr("hsdtqHSDTQ",*inptr)) {
|
sz = tolower(*inptr);
|
sz = tolower(*inptr);
|
inptr++;
|
inptr++;
|
}
|
}
|
else
|
else
|
error("Illegal float size");
|
error("Illegal float size");
|
}
|
}
|
switch(sz) {
|
switch(sz) {
|
case 'h': sz = 0; break;
|
case 'h': sz = 0; break;
|
case 's': sz = 1; break;
|
case 's': sz = 1; break;
|
case 'd': sz = 2; break;
|
case 'd': sz = 2; break;
|
case 't': sz = 3; break;
|
case 't': sz = 3; break;
|
case 'q': sz = 4; break;
|
case 'q': sz = 4; break;
|
default: sz = 3; break;
|
default: sz = 3; break;
|
}
|
}
|
return (sz);
|
return (sz);
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void emit_insn(int64_t oc, int can_compress, int sz)
|
static void emit_insn(int64_t oc, int can_compress, int sz)
|
{
|
{
|
int ndx;
|
int ndx;
|
|
|
|
switch (sz) {
|
|
case 6: oc = oc & 0xffffffffffffLL; break;// 48-bits max
|
|
case 4: oc = oc & 0xffffffffLL; break;
|
|
default: oc = oc & 0xffffLL; break;
|
|
}
|
|
if (sz > 2) {
|
if (pass==3 && can_compress && gCanCompress) {
|
if (pass==3 && can_compress && gCanCompress) {
|
for (ndx = 0; ndx < htblmax; ndx++) {
|
for (ndx = 0; ndx < htblmax; ndx++) {
|
if ((int)oc == hTable[ndx].opcode) {
|
if (oc == hTable[ndx].opcode) {
|
hTable[ndx].count++;
|
hTable[ndx].count++;
|
return;
|
return;
|
}
|
}
|
}
|
}
|
if (htblmax < 100000) {
|
if (htblmax < 100000) {
|
hTable[htblmax].opcode = (int)oc;
|
hTable[htblmax].opcode = oc;
|
hTable[htblmax].count = 1;
|
hTable[htblmax].count = 1;
|
htblmax++;
|
htblmax++;
|
return;
|
return;
|
}
|
}
|
error("Too many instructions");
|
error("Too many instructions");
|
return;
|
return;
|
}
|
}
|
|
}
|
if (pass > 3) {
|
if (pass > 3) {
|
if (can_compress && gCanCompress) {
|
if (can_compress && gCanCompress && sz > 2) {
|
for (ndx = 0; ndx < min(128,htblmax); ndx++) {
|
for (ndx = 0; ndx < min(256, htblmax); ndx++) {
|
if ((int)oc == hTable[ndx].opcode) {
|
if (oc == hTable[ndx].opcode) {
|
emitCode(((ndx << 6)|0x3F) & 0xff);
|
emitCode(0x2D);
|
emitCode(((ndx << 6)|0x3F) >> 8);
|
emitCode(ndx);
|
num_bytes += 2;
|
num_bytes += 2;
|
num_insns += 1;
|
num_insns += 1;
|
|
num_cinsns += 1;
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (sz==2) {
|
if (sz==2) {
|
emitCode(oc & 255);
|
emitCode(oc & 255);
|
emitCode((oc >> 8) & 255);
|
emitCode((oc >> 8) & 255);
|
num_bytes += 2;
|
num_bytes += 2;
|
num_insns += 1;
|
num_insns += 1;
|
num_cinsns += 1;
|
num_cinsns += 1;
|
return;
|
return;
|
}
|
}
|
if (sz == 4) {
|
if (sz == 4) {
|
emitCode(oc & 255);
|
emitCode(oc & 255);
|
emitCode((oc >> 8) & 255);
|
emitCode((oc >> 8) & 255);
|
emitCode((oc >> 16) & 255);
|
emitCode((oc >> 16) & 255);
|
emitCode((oc >> 24) & 255);
|
emitCode((oc >> 24) & 255);
|
num_bytes += 4;
|
num_bytes += 4;
|
num_insns += 1;
|
num_insns += 1;
|
return;
|
return;
|
}
|
}
|
emitCode(oc & 255);
|
emitCode(oc & 255);
|
emitCode((oc >> 8) & 255);
|
emitCode((oc >> 8) & 255);
|
emitCode((oc >> 16) & 255);
|
emitCode((oc >> 16) & 255);
|
emitCode((oc >> 24) & 255);
|
emitCode((oc >> 24) & 255);
|
emitCode((oc >> 32LL) & 255);
|
emitCode((oc >> 32LL) & 255);
|
emitCode((oc >> 40LL) & 255);
|
emitCode((oc >> 40LL) & 255);
|
num_bytes += 6;
|
num_bytes += 6;
|
//if (sz==3) {
|
|
// emitCode((int)(oc >> 16));
|
|
// num_bytes += 2;
|
|
// emitCode(oc >> 32);
|
|
// num_bytes += 2;
|
|
//}
|
|
num_insns += 1;
|
num_insns += 1;
|
/*
|
|
if (processOpt==2) {
|
|
for (ndx = 0; ndx < htblmax; ndx++) {
|
|
if (oc == hTable[ndx].opcode) {
|
|
printf("found opcode\n");
|
|
emitAlignedCode(((ndx & 8) << 4)|0x50|(ndx & 0x7));
|
|
emitCode(ndx >> 4);
|
|
return;
|
|
}
|
|
}
|
|
emitAlignedCode(oc & 255);
|
|
emitCode((oc >> 8) & 255);
|
|
emitCode((oc >> 16) & 255);
|
|
emitCode((oc >> 24) & 255);
|
|
}
|
|
else {
|
|
emitAlignedCode(oc & 255);
|
|
emitCode((oc >> 8) & 255);
|
|
emitCode((oc >> 16) & 255);
|
|
emitCode((oc >> 24) & 255);
|
|
*/
|
|
}
|
}
|
}
|
}
|
|
|
void LoadConstant(int64_t val, int rg)
|
void LoadConstant(int64_t val, int rg)
|
{
|
{
|
if (IsNBit(val, 14)) {
|
if (IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(rg << 13) |
|
(rg << 13) |
|
0x09, !expand_flag, 4); // ORI
|
0x09, !expand_flag, 4); // ORI
|
return;
|
return;
|
}
|
}
|
if (IsNBit(val, 30)) {
|
if (IsNBit(val, 30)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(rg << 13) |
|
(rg << 13) |
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6);
|
0x09, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
if (IsNBit(val, 49)) {
|
if (IsNBit(val, 49)) {
|
emit_insn(
|
emit_insn(
|
((val >> 30) << 13LL) |
|
((val >> 30LL) << 13LL) |
|
(rg << 8) |
|
(rg << 8) |
|
0x27, !expand_flag, 4); // LUI
|
0x27, !expand_flag, 4); // LUI
|
if (((val >> 20) & 0xfffffLL) != 0)
|
if (((val >> 20LL) & 0xfffffLL) != 0)
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(rg << 13) |
|
(rg << 13) |
|
|
(rg << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6);
|
0x09, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
// Won't fit into 49 bits, assume 64 bit constant
|
// Won't fit into 49 bits, assume 64 bit constant
|
emit_insn(
|
emit_insn(
|
((val >> 30) << 13LL) |
|
((val >> 30) << 13LL) |
|
(rg << 8) |
|
(rg << 8) |
|
0x27, !expand_flag, 6); // LUI
|
0x27, !expand_flag, 6); // LUI
|
if (((val >> 20) & 0xfffffLL) != 0)
|
if (((val >> 20) & 0xfffffLL) != 0)
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(rg << 13) |
|
(rg << 13) |
|
|
(rg << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6); // ORI
|
0x09, !expand_flag, 6); // ORI
|
return;
|
return;
|
}
|
}
|
|
|
static void Lui34(int64_t val, int rg)
|
static void Lui34(int64_t val, int rg)
|
{
|
{
|
if (IsNBit(val, 49)) {
|
if (IsNBit(val, 49)) {
|
emit_insn(
|
emit_insn(
|
((val >> 30LL) << 13LL) |
|
((val >> 30LL) << 13LL) |
|
(rg << 8) |
|
(rg << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x27, !expand_flag, 4
|
0x27, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((val >> 30LL) << 13LL) |
|
((val >> 30LL) << 13LL) |
|
(rg << 8) |
|
(rg << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x27, !expand_flag, 6
|
0x27, !expand_flag, 6
|
);
|
);
|
}
|
}
|
|
|
void LoadConstant12(int64_t val, int rg)
|
void LoadConstant12(int64_t val, int rg)
|
{
|
{
|
if (val & 0x800) {
|
if (val & 0x800) {
|
emit_insn(
|
emit_insn(
|
(0 << 16) |
|
(0 << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
0x09,!expand_flag,4); // ORI
|
0x09,!expand_flag,4); // ORI
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
(0 << 6) |
|
(0 << 6) |
|
0x1A,!expand_flag,4); // ORQ0
|
0x1A,!expand_flag,4); // ORQ0
|
}
|
}
|
else {
|
else {
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
0x09,!expand_flag,4); // ORI
|
0x09,!expand_flag,4); // ORI
|
}
|
}
|
val >>= 16;
|
val >>= 16;
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
(1 << 6) |
|
(1 << 6) |
|
0x1A,!expand_flag,4); // ORQ1
|
0x1A,!expand_flag,4); // ORQ1
|
val >>= 16;
|
val >>= 16;
|
if (val != 0) {
|
if (val != 0) {
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
(2 << 6) |
|
(2 << 6) |
|
0x1A,!expand_flag,4); // ORQ2
|
0x1A,!expand_flag,4); // ORQ2
|
}
|
}
|
val >>= 16;
|
val >>= 16;
|
if (val != 0) {
|
if (val != 0) {
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(rg << 11) |
|
(rg << 11) |
|
(0 << 6) |
|
(0 << 6) |
|
(3 << 6) |
|
(3 << 6) |
|
0x1A,!expand_flag,4); // ORQ3
|
0x1A,!expand_flag,4); // ORQ3
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
static void getSz(int *sz)
|
static void getSz(int *sz)
|
{
|
{
|
if (*inptr=='.')
|
if (*inptr=='.')
|
inptr++;
|
inptr++;
|
*sz = inptr[0];
|
*sz = inptr[0];
|
switch(*sz) {
|
switch(*sz) {
|
case 'b': case 'B':
|
case 'b': case 'B':
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
inptr++;
|
inptr++;
|
*sz = 4;
|
*sz = 4;
|
}
|
}
|
else
|
else
|
*sz = 0;
|
*sz = 0;
|
break;
|
break;
|
case 'c': case 'C':
|
case 'c': case 'C':
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
inptr++;
|
inptr++;
|
*sz = 5;
|
*sz = 5;
|
}
|
}
|
else
|
else
|
*sz = 1;
|
*sz = 1;
|
break;
|
break;
|
case 'h': case 'H':
|
case 'h': case 'H':
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
inptr++;
|
inptr++;
|
*sz = 6;
|
*sz = 6;
|
}
|
}
|
else
|
else
|
*sz = 2;
|
*sz = 2;
|
break;
|
break;
|
case 'w': case 'W':
|
case 'w': case 'W':
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
if (inptr[1] == 'p' || inptr[1] == 'P') {
|
inptr++;
|
inptr++;
|
*sz = 7;
|
*sz = 7;
|
}
|
}
|
else
|
else
|
*sz = 3;
|
*sz = 3;
|
break;
|
break;
|
case 'd': case 'D': *sz = 0x83; break;
|
case 'd': case 'D': *sz = 0x83; break;
|
case 'i': case 'I': *sz = 0x43; break;
|
case 'i': case 'I': *sz = 0x43; break;
|
default:
|
default:
|
error("Bad size");
|
error("Bad size");
|
*sz = 3;
|
*sz = 3;
|
}
|
}
|
inptr += 1;
|
inptr += 1;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// Get memory aquire and release bits.
|
// Get memory aquire and release bits.
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void GetArBits(int64_t *aq, int64_t *rl)
|
static void GetArBits(int64_t *aq, int64_t *rl)
|
{
|
{
|
*aq = *rl = 0;
|
*aq = *rl = 0;
|
while (*inptr == '.') {
|
while (*inptr == '.') {
|
inptr++;
|
inptr++;
|
if (inptr[0] != 'a' && inptr[0] != 'A' && inptr[0] != 'r' && inptr[0] != 'R')
|
if (inptr[0] != 'a' && inptr[0] != 'A' && inptr[0] != 'r' && inptr[0] != 'R')
|
break;
|
break;
|
if ((inptr[0] == 'a' || inptr[0] == 'A') && (inptr[1] == 'q' || inptr[1] == 'Q')) {
|
if ((inptr[0] == 'a' || inptr[0] == 'A') && (inptr[1] == 'q' || inptr[1] == 'Q')) {
|
inptr += 2;
|
inptr += 2;
|
*aq = 1;
|
*aq = 1;
|
}
|
}
|
if ((inptr[0] == 'r' || inptr[0] == 'R') && (inptr[1] == 'l' || inptr[1] == 'L')) {
|
if ((inptr[0] == 'r' || inptr[0] == 'R') && (inptr[1] == 'l' || inptr[1] == 'L')) {
|
inptr += 2;
|
inptr += 2;
|
*rl = 1;
|
*rl = 1;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// addi r1,r2,#1234
|
// addi r1,r2,#1234
|
//
|
//
|
// A value that is too large has to be loaded into a register then the
|
// A value that is too large has to be loaded into a register then the
|
// instruction converted to a registered form.
|
// instruction converted to a registered form.
|
// So
|
// So
|
// addi r1,r2,#$12345678
|
// addi r1,r2,#$12345678
|
// Becomes:
|
// Becomes:
|
// ldiq1 r52,#$00123
|
// ldiq1 r52,#$00123
|
// oriq0 r52,#$45678
|
// oriq0 r52,#$45678
|
// addi r1,r2,r52
|
// addi r1,r2,r52
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_riop(int64_t opcode6)
|
static void process_riop(int64_t opcode6)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt, Rtp;
|
int Rt, Rtp;
|
char *p;
|
char *p;
|
int64_t val;
|
int64_t val;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
if (opcode6==-4LL) { // subi
|
if (opcode6==-4LL) { // subi
|
val = -val;
|
val = -val;
|
opcode6 = 0x04LL; // change to addi
|
opcode6 = 0x04LL; // change to addi
|
}
|
}
|
// ADDI
|
// ADDI
|
if (opcode6 == 0x04) {
|
if (opcode6 == 0x04) {
|
if (Ra == Rt) {
|
if (Ra == Rt) {
|
if (Rt == regSP) {
|
if (Rt == regSP) {
|
if (val >= -128 && val < 128 && ((val & 7) == 0)) {
|
if (val >= -128 && val < 128 && ((val & 7) == 0)) {
|
emit_insn(
|
emit_insn(
|
(0 << 12) |
|
(0 << 12) |
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
regSP, 0, 2);
|
regSP, 0, 2);
|
goto xit;
|
goto xit;
|
}
|
}
|
}
|
}
|
else {
|
else {
|
if (val >= -16 && val < 16) {
|
if (val >= -16 && val < 16) {
|
emit_insn(
|
emit_insn(
|
(0 << 12) |
|
(0 << 12) |
|
(((val >> 1) & 0x0F) << 8) |
|
(((val >> 1) & 0x0F) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
((val & 0x1) << 5) |
|
((val & 0x1) << 5) |
|
Ra, 0, 2);
|
Ra, 0, 2);
|
goto xit;
|
goto xit;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
// Compress ANDI ?
|
// Compress ANDI ?
|
if (opcode6 == 0x08 && Ra == Rt && Ra != 0) {
|
if (opcode6 == 0x08 && Ra == Rt && Ra != 0) {
|
if (val > -16 && val < 16) {
|
if (val > -16 && val < 16) {
|
emit_insn(
|
emit_insn(
|
(2 << 12) |
|
(2 << 12) |
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
Rt, 0, 2
|
Rt, 0, 2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
}
|
}
|
// Compress ORI ?
|
// Compress ORI ?
|
if (opcode6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Ra)) >= 0) {
|
if (opcode6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Ra)) >= 0) {
|
if (val > -16 && val < 16) {
|
if (val > -16 && val < 16) {
|
emit_insn(
|
emit_insn(
|
(4 << 12) |
|
(4 << 12) |
|
(((val >> 1) & 0x0f) << 8) |
|
(((val >> 1) & 0x0f) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(2 << 4) |
|
(2 << 4) |
|
((val & 1) << 3) |
|
((val & 1) << 3) |
|
Rtp, 0, 2
|
Rtp, 0, 2
|
);
|
);
|
}
|
}
|
goto xit;
|
goto xit;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 30)) {
|
if (!IsNBit(val, 30)) {
|
Lui34(val, 23);
|
Lui34(val, 23);
|
emit_insn(
|
emit_insn(
|
(val << 18) |
|
(val << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(23 << 8) |
|
(23 << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6 // ORI
|
0x09, !expand_flag, 6 // ORI
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26LL) |
|
(opcode6 << 26LL) |
|
(sz << 23) | // set size to word size op
|
(sz << 23) | // set size to word size op
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02, !expand_flag, 4);
|
0x02, !expand_flag, 4);
|
goto xit;
|
goto xit;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag, 6);
|
opcode6, !expand_flag, 6);
|
goto xit;
|
goto xit;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 18)|(Rt << 13)|(Ra << 8)|opcode6,!expand_flag,4);
|
(val << 18)|(Rt << 13)|(Ra << 8)|opcode6,!expand_flag,4);
|
xit:
|
xit:
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// slti r1,r2,#1234
|
// slti r1,r2,#1234
|
//
|
//
|
// A value that is too large has to be loaded into a register then the
|
// A value that is too large has to be loaded into a register then the
|
// instruction converted to a registered form.
|
// instruction converted to a registered form.
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_setiop(int64_t opcode6)
|
static void process_setiop(int64_t opcode6)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int64_t val;
|
int64_t val;
|
|
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
if (!IsNBit(val, 30)) {
|
if (!IsNBit(val, 30)) {
|
LoadConstant(val, 23);
|
LoadConstant(val, 23);
|
switch (opcode6)
|
switch (opcode6)
|
{
|
{
|
case 0x06:
|
case 0x06:
|
case 0x07:
|
case 0x07:
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26) | // SLT / SLTU
|
(opcode6 << 26) | // SLT / SLTU
|
(3 << 23) |
|
(3 << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4);
|
0x02, !expand_flag, 4);
|
return;
|
return;
|
case 0x2C: // SGTI
|
case 0x2C: // SGTI
|
emit_insn(
|
emit_insn(
|
(0x28 << 26) | // SLE
|
(0x28 << 26) | // SLE
|
(3 << 23) |
|
(3 << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02,!expand_flag,4)
|
0x02,!expand_flag,4)
|
;
|
;
|
emit_insn(
|
emit_insn(
|
(0x01 << 26) |
|
(0x01 << 26) |
|
(3 << 23) |
|
(3 << 23) |
|
(3 << 18) | // COM
|
(3 << 18) | // COM
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02,!expand_flag,4
|
0x02,!expand_flag,4
|
);
|
);
|
return;
|
return;
|
case 0x1C: // SGTUI
|
case 0x1C: // SGTUI
|
emit_insn(
|
emit_insn(
|
(0x29 << 26) | // SLEU
|
(0x29 << 26) | // SLEU
|
(3 << 23) |
|
(3 << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4)
|
0x02, !expand_flag, 4)
|
;
|
;
|
emit_insn(
|
emit_insn(
|
(0x01 << 26) |
|
(0x01 << 26) |
|
(3 << 23) |
|
(3 << 23) |
|
(3 << 18) | // COM
|
(3 << 18) | // COM
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
error("Illegal set immediate instruction");
|
error("Illegal set immediate instruction");
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18) |
|
(val << 18) |
|
(Rt << 13) | (Ra << 8) |
|
(Rt << 13) | (Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag,6);
|
opcode6, !expand_flag,6);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 18)|
|
(val << 18)|
|
(Rt << 13)|
|
(Rt << 13)|
|
(Ra << 8)|
|
(Ra << 8)|
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
}
|
}
|
|
|
static void process_setop(int64_t opcode6)
|
static void process_setop(int64_t opcode6)
|
{
|
{
|
int Ra, Rb, Rt;
|
int Ra, Rb, Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
sz &= 7;
|
sz &= 7;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
if (Rb == -1) {
|
if (Rb == -1) {
|
inptr = p;
|
inptr = p;
|
process_setiop(opcode6);
|
process_setiop(opcode6);
|
return;
|
return;
|
}
|
}
|
switch (opcode6)
|
switch (opcode6)
|
{
|
{
|
case -6: // SGE = !SLT
|
case -6: // SGE = !SLT
|
case -7: // SGEU = !SLTU
|
case -7: // SGEU = !SLTU
|
emit_insn(
|
emit_insn(
|
(-opcode6 << 26) |
|
(-opcode6 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(1 << 26) |
|
(1 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(3 << 18) | // COM
|
(3 << 18) | // COM
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
case -0x2C: // SGT = !SLE
|
case -0x2C: // SGT = !SLE
|
emit_insn(
|
emit_insn(
|
(0x28 << 26) |
|
(0x28 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(1 << 26) |
|
(1 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(3 << 18) | // COM
|
(3 << 18) | // COM
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
case -0x1C: // SGTU = !SLEU
|
case -0x1C: // SGTU = !SLEU
|
emit_insn(
|
emit_insn(
|
(0x29 << 26) |
|
(0x29 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(1 << 26) |
|
(1 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(3 << 18) | // COM
|
(3 << 18) | // COM
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26) |
|
(opcode6 << 26) |
|
(sz << 23) |
|
(sz << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02, !expand_flag, 4
|
0x02, !expand_flag, 4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// add r1,r2,r3
|
// add r1,r2,r3
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_rrop(int64_t funct6, int64_t iop)
|
static void process_rrop(int64_t funct6, int64_t iop)
|
{
|
{
|
int Ra,Rb,Rt,Rbp,Rtp;
|
int Ra,Rb,Rt,Rbp,Rtp;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p=='.')
|
if (*p=='.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
if (iop < 0 && iop!=-4)
|
if (iop < 0 && iop!=-4)
|
error("Immediate mode not supported");
|
error("Immediate mode not supported");
|
inptr = p;
|
inptr = p;
|
process_riop(iop);
|
process_riop(iop);
|
return;
|
return;
|
}
|
}
|
prevToken();
|
prevToken();
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
// Compress ADD
|
// Compress ADD
|
if (funct6 == 0x04 && Ra == Rt) {
|
if (funct6 == 0x04 && Ra == Rt) {
|
emit_insn(
|
emit_insn(
|
(1 << 12) |
|
(1 << 12) |
|
(((Ra >> 1) & 0xF) << 8) |
|
(((Ra >> 1) & 0xF) << 8) |
|
(3 << 6) |
|
(3 << 6) |
|
((Ra & 1) << 5) |
|
((Ra & 1) << 5) |
|
(Rt),
|
(Rt),
|
0,2
|
0,2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
// Compress SUB
|
// Compress SUB
|
if (funct6 == 0x05 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
if (funct6 == 0x05 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
emit_insn(
|
emit_insn(
|
(4 << 12) |
|
(4 << 12) |
|
(0 << 10) |
|
(0 << 10) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(3 << 4) |
|
(3 << 4) |
|
((Rbp & 1) << 3) |
|
((Rbp & 1) << 3) |
|
(Rtp),
|
(Rtp),
|
0, 2
|
0, 2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
// Compress AND
|
// Compress AND
|
if (funct6 == 0x08 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
if (funct6 == 0x08 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
emit_insn(
|
emit_insn(
|
(4 << 12) |
|
(4 << 12) |
|
(1 << 10) |
|
(1 << 10) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(3 << 4) |
|
(3 << 4) |
|
((Rbp & 1) << 3) |
|
((Rbp & 1) << 3) |
|
(Rtp),
|
(Rtp),
|
0, 2
|
0, 2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
// Compress OR
|
// Compress OR
|
if (funct6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
if (funct6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
emit_insn(
|
emit_insn(
|
(4 << 12) |
|
(4 << 12) |
|
(2 << 10) |
|
(2 << 10) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(3 << 4) |
|
(3 << 4) |
|
((Rbp & 1) << 3) |
|
((Rbp & 1) << 3) |
|
(Rtp),
|
(Rtp),
|
0, 2
|
0, 2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
// Compress XOR
|
// Compress XOR
|
if (funct6 == 0x0A && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
if (funct6 == 0x0A && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
|
emit_insn(
|
emit_insn(
|
(4 << 12) |
|
(4 << 12) |
|
(3 << 10) |
|
(3 << 10) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(((Rbp >> 1) & 0x3) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(3 << 4) |
|
(3 << 4) |
|
((Rbp & 1) << 3) |
|
((Rbp & 1) << 3) |
|
(Rtp),
|
(Rtp),
|
0, 2
|
0, 2
|
);
|
);
|
goto xit;
|
goto xit;
|
}
|
}
|
//prevToken();
|
//prevToken();
|
if (funct6==0x2E || funct6==0x2C || funct6==0x2D) {
|
if (funct6==0x2E || funct6==0x2C || funct6==0x2D) {
|
funct6 += 0x10; // change to divmod
|
funct6 += 0x10; // change to divmod
|
emit_insn((funct6<<26LL)||(1<<23)||(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
emit_insn((funct6<<26LL)||(1<<23)||(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
goto xit;
|
goto xit;
|
}
|
}
|
else if (funct6==0x3C || funct6==0x3D || funct6==0x3E) {
|
else if (funct6==0x3C || funct6==0x3D || funct6==0x3E) {
|
emit_insn((funct6<<26LL)||(0<<23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
emit_insn((funct6<<26LL)||(0<<23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
goto xit;
|
goto xit;
|
}
|
}
|
emit_insn((funct6<<26LL)|(sz << 23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
emit_insn((funct6<<26LL)|(sz << 23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
|
xit:
|
xit:
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// or r1,r2,r3,r4
|
// or r1,r2,r3,r4
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_rrrop(int64_t funct6)
|
static void process_rrrop(int64_t funct6)
|
{
|
{
|
int Ra, Rb, Rc = 0, Rt;
|
int Ra, Rb, Rc = 0, Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token == '#') {
|
if (token == '#') {
|
inptr = p;
|
inptr = p;
|
process_riop(funct6);
|
process_riop(funct6);
|
return;
|
return;
|
}
|
}
|
prevToken();
|
prevToken();
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
if (token == ',') {
|
if (token == ',') {
|
NextToken();
|
NextToken();
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
}
|
}
|
else {
|
else {
|
switch (funct6) {
|
switch (funct6) {
|
case 0x08: Rc = Rb; break; // and
|
case 0x08: Rc = Rb; break; // and
|
case 0x09: Rc = 0; break; // or
|
case 0x09: Rc = 0; break; // or
|
case 0x0A: Rc = 0; break; // xor
|
case 0x0A: Rc = 0; break; // xor
|
}
|
}
|
}
|
}
|
emit_insn((funct6 << 34LL) | (sz << 24) | (Rt << 27) | (Rc << 18) | (Rb << 12) | (Ra << 6) | 0x42, !expand_flag, 5);
|
emit_insn((funct6 << 34LL) | (sz << 24) | (Rt << 27) | (Rc << 18) | (Rb << 12) | (Ra << 6) | 0x42, !expand_flag, 5);
|
}
|
}
|
|
|
static void process_cmove(int64_t funct6)
|
static void process_cmove(int64_t funct6)
|
{
|
{
|
int Ra, Rb, Rc = 0, Rt;
|
int Ra, Rb, Rc = 0, Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
int64_t val;
|
int64_t val;
|
|
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token == '#') {
|
if (token == '#') {
|
val = expr();
|
val = expr();
|
emit_insn(
|
emit_insn(
|
(funct6 << 42LL) |
|
(funct6 << 42LL) |
|
(1LL << 41LL) |
|
(1LL << 41LL) |
|
(((val >> 5) & 0x7ff) << 28) |
|
(((val >> 5) & 0x7ff) << 28) |
|
(Rt << 23) |
|
(Rt << 23) |
|
((val & 0x1f) << 18) |
|
((val & 0x1f) << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02, !expand_flag, 6);
|
0x02, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
prevToken();
|
prevToken();
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
emit_insn((funct6 << 42LL) | (Rt << 23) | (Rc << 18) | (Rb << 13) | (Ra << 8) | 0x02, !expand_flag, 6);
|
emit_insn((funct6 << 42LL) | (Rt << 23) | (Rc << 18) | (Rb << 13) | (Ra << 8) | 0x02, !expand_flag, 6);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// jmp main
|
// jmp main
|
// jal [r19]
|
// jal [r19]
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_jal(int64_t oc)
|
static void process_jal(int64_t oc)
|
{
|
{
|
int64_t addr, val;
|
int64_t addr, val;
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
bool noRt;
|
bool noRt;
|
char *p;
|
char *p;
|
|
|
noRt = false;
|
noRt = false;
|
Ra = 0;
|
Ra = 0;
|
Rt = 0;
|
Rt = 0;
|
p = inptr;
|
p = inptr;
|
NextToken();
|
NextToken();
|
if (token == '(' || token == '[') {
|
if (token == '(' || token == '[') {
|
j1:
|
j1:
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra == -1) {
|
if (Ra == -1) {
|
printf("Expecting a register\r\n");
|
printf("Expecting a register\r\n");
|
goto xit;
|
goto xit;
|
}
|
}
|
// Simple jmp [Rn]
|
// Simple jmp [Rn]
|
if (token != ')' && token != ']')
|
if (token != ')' && token != ']')
|
printf("Missing close bracket %d\n", lineno);
|
printf("Missing close bracket %d\n", lineno);
|
emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4);
|
emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4);
|
goto xit;
|
goto xit;
|
}
|
}
|
else
|
else
|
inptr = p;
|
inptr = p;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
if (Rt >= 0) {
|
if (Rt >= 0) {
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
// jal Rt,[Ra]
|
// jal Rt,[Ra]
|
if (token=='(' || token=='[')
|
if (token=='(' || token=='[')
|
goto j1;
|
goto j1;
|
}
|
}
|
else {
|
else {
|
Rt = 0;
|
Rt = 0;
|
noRt = true;
|
noRt = true;
|
}
|
}
|
addr = expr();
|
addr = expr();
|
// d(Rn)?
|
// d(Rn)?
|
//NextToken();
|
//NextToken();
|
if (token=='(' || token=='[') {
|
if (token=='(' || token=='[') {
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra==-1) {
|
if (Ra==-1) {
|
printf("Illegal jump address mode.\r\n");
|
printf("Illegal jump address mode.\r\n");
|
Ra = 0;
|
Ra = 0;
|
}
|
}
|
if (Ra==regSP) // program counter relative ?
|
if (Ra==regSP) // program counter relative ?
|
addr -= code_address;
|
addr -= code_address;
|
}
|
}
|
val = addr;
|
val = addr;
|
if (IsNBit(val, 14)) {
|
if (IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18) |
|
(val << 18) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x18, !expand_flag, 4);
|
0x18, !expand_flag, 4);
|
goto xit;
|
goto xit;
|
}
|
}
|
if (IsNBit(val, 30)) {
|
if (IsNBit(val, 30)) {
|
emit_insn(
|
emit_insn(
|
(val << 18) |
|
(val << 18) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x18, !expand_flag, 6);
|
0x18, !expand_flag, 6);
|
goto xit;
|
goto xit;
|
}
|
}
|
|
|
{
|
{
|
LoadConstant(val, 23);
|
LoadConstant(val, 23);
|
if (Ra != 0) {
|
if (Ra != 0) {
|
// add r23,r23,Ra
|
// add r23,r23,Ra
|
emit_insn(
|
emit_insn(
|
(0x04LL << 26LL) |
|
(0x04LL << 26LL) |
|
(3 << 23) |
|
(3 << 23) |
|
(23 << 18) |
|
(23 << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02, 0, 4
|
0x02, 0, 4
|
);
|
);
|
// jal Rt,r23
|
// jal Rt,r23
|
emit_insn(
|
emit_insn(
|
(0 << 18) |
|
(0 << 18) |
|
(Rt << 12) |
|
(Rt << 12) |
|
(23 << 8) | 0x18, !expand_flag, 4);
|
(23 << 8) | 0x18, !expand_flag, 4);
|
goto xit;
|
goto xit;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(Rt << 12) |
|
(Rt << 12) |
|
(23 << 8) | 0x18, !expand_flag, 4);
|
(23 << 8) | 0x18, !expand_flag, 4);
|
goto xit;
|
goto xit;
|
}
|
}
|
xit:
|
xit:
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// subui r1,r2,#1234
|
// subui r1,r2,#1234
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
/*
|
/*
|
static void process_riop(int oc)
|
static void process_riop(int oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int64_t val;
|
int64_t val;
|
|
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
|
|
if (lastsym != (SYM *)NULL)
|
if (lastsym != (SYM *)NULL)
|
emitImm16(val,!lastsym->defined);
|
emitImm16(val,!lastsym->defined);
|
else
|
else
|
emitImm16(val,0);
|
emitImm16(val,0);
|
|
|
emitImm16(val,lastsym!=(SYM*)NULL);
|
emitImm16(val,lastsym!=(SYM*)NULL);
|
emitAlignedCode(oc);
|
emitAlignedCode(oc);
|
if (bGen)
|
if (bGen)
|
if (lastsym && !use_gp) {
|
if (lastsym && !use_gp) {
|
if( lastsym->segment < 5)
|
if( lastsym->segment < 5)
|
sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
|
sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
|
(lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
|
(lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
|
}
|
}
|
emitCode(Ra);
|
emitCode(Ra);
|
emitCode(Rt);
|
emitCode(Rt);
|
emitCode(val & 255);
|
emitCode(val & 255);
|
emitCode((val >> 8) & 255);
|
emitCode((val >> 8) & 255);
|
}
|
}
|
*/
|
*/
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// fabs.d r1,r2[,rm]
|
// fabs.d r1,r2[,rm]
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_fprop(int64_t oc)
|
static void process_fprop(int64_t oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int fmt;
|
int fmt;
|
int64_t rm;
|
int64_t rm;
|
|
|
rm = 0;
|
rm = 0;
|
fmt = GetFPSize();
|
fmt = GetFPSize();
|
p = inptr;
|
p = inptr;
|
Rt = getFPRegister();
|
Rt = getFPRegister();
|
need(',');
|
need(',');
|
Ra = getFPRegister();
|
Ra = getFPRegister();
|
if (token==',')
|
if (token==',')
|
rm = getFPRoundMode();
|
rm = getFPRoundMode();
|
// prevToken();
|
// prevToken();
|
if (fmt != 2) {
|
if (fmt != 2) {
|
emit_insn(
|
emit_insn(
|
(oc << 42LL) |
|
(oc << 42LL) |
|
((int64_t)fmt << 31LL) |
|
((int64_t)fmt << 31LL) |
|
(rm << 28) |
|
(rm << 28) |
|
(Rt << 23) |
|
(Rt << 23) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F, !expand_flag, 6
|
0x0F, !expand_flag, 6
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(oc << 26LL) |
|
(oc << 26LL) |
|
(rm << 23) |
|
(rm << 23) |
|
(Rt << 18)|
|
(Rt << 18)|
|
(0 << 13)|
|
(0 << 13)|
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F,!expand_flag,4
|
0x0F,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// fabs.d r1,r2[,rm]
|
// fabs.d r1,r2[,rm]
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_itof(int64_t oc)
|
static void process_itof(int64_t oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int fmt;
|
int fmt;
|
int64_t rm;
|
int64_t rm;
|
|
|
rm = 0;
|
rm = 0;
|
fmt = GetFPSize();
|
fmt = GetFPSize();
|
p = inptr;
|
p = inptr;
|
Rt = getFPRegister();
|
Rt = getFPRegister();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (token==',')
|
if (token==',')
|
rm = getFPRoundMode();
|
rm = getFPRoundMode();
|
// prevToken();
|
// prevToken();
|
if (fmt != 2) {
|
if (fmt != 2) {
|
emit_insn(
|
emit_insn(
|
(oc << 42LL) |
|
(oc << 42LL) |
|
(fmt << 31LL) |
|
(fmt << 31LL) |
|
(rm << 28LL) |
|
(rm << 28LL) |
|
(Rt << 23) |
|
(Rt << 23) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F, !expand_flag, 6
|
0x0F, !expand_flag, 6
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(oc << 26LL) |
|
(oc << 26LL) |
|
(rm << 23LL)|
|
(rm << 23LL)|
|
(Rt << 18)|
|
(Rt << 18)|
|
(0 << 13)|
|
(0 << 13)|
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F,!expand_flag,4
|
0x0F,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
static void process_ftoi(int64_t oc)
|
static void process_ftoi(int64_t oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int fmt;
|
int fmt;
|
int64_t rm;
|
int64_t rm;
|
|
|
rm = 0;
|
rm = 0;
|
fmt = GetFPSize();
|
fmt = GetFPSize();
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getFPRegister();
|
Ra = getFPRegister();
|
if (token == ',')
|
if (token == ',')
|
rm = getFPRoundMode();
|
rm = getFPRoundMode();
|
// prevToken();
|
// prevToken();
|
if (fmt != 2) {
|
if (fmt != 2) {
|
emit_insn(
|
emit_insn(
|
(oc << 42LL) |
|
(oc << 42LL) |
|
(fmt << 31LL) |
|
(fmt << 31LL) |
|
(rm << 28LL) |
|
(rm << 28LL) |
|
(Rt << 23) |
|
(Rt << 23) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F, !expand_flag, 6
|
0x0F, !expand_flag, 6
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(oc << 26LL) |
|
(oc << 26LL) |
|
(rm << 23LL) |
|
(rm << 23LL) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F, !expand_flag, 4
|
0x0F, !expand_flag, 4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// fadd.d r1,r2,r12[,rm]
|
// fadd.d r1,r2,r12[,rm]
|
// fcmp.d r1,r3,r10[,rm]
|
// fcmp.d r1,r3,r10[,rm]
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_fprrop(int64_t oc)
|
static void process_fprrop(int64_t oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rb;
|
int Rb;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int fmt;
|
int fmt;
|
int64_t rm;
|
int64_t rm;
|
|
|
rm = 0;
|
rm = 0;
|
fmt = GetFPSize();
|
fmt = GetFPSize();
|
p = inptr;
|
p = inptr;
|
if (oc==0x01) // fcmp
|
if (oc==0x01) // fcmp
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
else
|
else
|
Rt = getFPRegister();
|
Rt = getFPRegister();
|
need(',');
|
need(',');
|
Ra = getFPRegister();
|
Ra = getFPRegister();
|
need(',');
|
need(',');
|
Rb = getFPRegister();
|
Rb = getFPRegister();
|
if (token==',')
|
if (token==',')
|
rm = getFPRoundMode();
|
rm = getFPRoundMode();
|
// prevToken();
|
// prevToken();
|
if (fmt != 2) {
|
if (fmt != 2) {
|
emit_insn(
|
emit_insn(
|
(oc << 42LL) |
|
(oc << 42LL) |
|
((int64_t)fmt << 31LL) |
|
((int64_t)fmt << 31LL) |
|
(rm << 28LL) |
|
(rm << 28LL) |
|
(Rt << 23) |
|
(Rt << 23) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x0F, !expand_flag, 6
|
0x0F, !expand_flag, 6
|
);
|
);
|
return;
|
return;
|
}
|
}
|
|
|
emit_insn(
|
emit_insn(
|
(oc << 26LL)|
|
(oc << 26LL)|
|
(rm << 23LL)|
|
(rm << 23LL)|
|
(Rt << 18)|
|
(Rt << 18)|
|
(Rb << 13)|
|
(Rb << 13)|
|
(Ra << 8) |
|
(Ra << 8) |
|
0x0F,!expand_flag,4
|
0x0F,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// fcx r0,#2
|
// fcx r0,#2
|
// fdx r1,#0
|
// fdx r1,#0
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_fpstat(int oc)
|
static void process_fpstat(int oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int64_t bits;
|
int64_t bits;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
bits = 0;
|
bits = 0;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (token==',') {
|
if (token==',') {
|
NextToken();
|
NextToken();
|
bits = expr();
|
bits = expr();
|
}
|
}
|
prevToken();
|
prevToken();
|
emit_insn(
|
emit_insn(
|
((bits & 0x3F) << 18) |
|
((bits & 0x3F) << 18) |
|
(oc << 12) |
|
(oc << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x36,!expand_flag,5
|
0x36,!expand_flag,5
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// not r3,r3
|
// not r3,r3
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_rop(int oc)
|
static void process_rop(int oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
int sz = 3;
|
int sz = 3;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
emit_insn(
|
emit_insn(
|
(1LL << 26LL) |
|
(1LL << 26LL) |
|
(sz << 23) |
|
(sz << 23) |
|
(oc << 18) |
|
(oc << 18) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02,!expand_flag,4
|
0x02,!expand_flag,4
|
);
|
);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// beqi r2,#123,label
|
// beqi r2,#123,label
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_beqi(int64_t opcode6, int64_t opcode3)
|
static void process_beqi(int64_t opcode6, int64_t opcode3)
|
{
|
{
|
int Ra, pred = 0;
|
int Ra, pred = 0;
|
int64_t val, imm;
|
int64_t val, imm;
|
int64_t disp;
|
int64_t disp;
|
int sz = 3;
|
int sz = 3;
|
char *p;
|
char *p;
|
bool isn48 = false;
|
bool isn48 = false;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
imm = expr();
|
imm = expr();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4LL);
|
disp = val - (code_address + 4LL);
|
if (!IsNBit(disp, 11)) {
|
if (!IsNBit(disp, 11)) {
|
disp = val - (code_address + 6LL);
|
disp = val - (code_address + 6LL);
|
isn48 = true;
|
isn48 = true;
|
}
|
}
|
disp >>= 1;
|
disp >>= 1;
|
if (!IsNBit(imm,8)) {
|
if (!IsNBit(imm,8)) {
|
//printf("Branch immediate too large: %d %I64d", lineno, imm);
|
//printf("Branch immediate too large: %d %I64d", lineno, imm);
|
isn48 = false;
|
isn48 = false;
|
LoadConstant(imm, 23);
|
LoadConstant(imm, 23);
|
disp = val - (code_address + 4LL);
|
disp = val - (code_address + 4LL);
|
if (!IsNBit(disp, 11)) {
|
if (!IsNBit(disp, 11)) {
|
disp = val - (code_address + 6LL);
|
disp = val - (code_address + 6LL);
|
isn48 = true;
|
isn48 = true;
|
}
|
}
|
disp >>= 1;
|
disp >>= 1;
|
emit_insn(
|
emit_insn(
|
(disp << 21LL) |
|
(disp << 21LL) |
|
(0x00 << 18) | // BEQ
|
(0x00 << 18) | // BEQ
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x30, !expand_flag, isn48 ? 6 : 4
|
0x30, !expand_flag, isn48 ? 6 : 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn((disp << 21LL) |
|
emit_insn((disp << 21LL) |
|
((imm & 0xFF) << 13) |
|
((imm & 0xFF) << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,isn48 ? 6 : 4
|
opcode6,!expand_flag,isn48 ? 6 : 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// beq r1,r2,label
|
// beq r1,r2,label
|
// bne r2,r3,r4
|
// bne r2,r3,r4
|
//
|
//
|
// When opcode4 is negative it indicates to swap the a and b registers. This
|
// When opcode4 is negative it indicates to swap the a and b registers. This
|
// allows source code to use alternate forms of branch conditions.
|
// allows source code to use alternate forms of branch conditions.
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_bcc(int opcode6, int opcode4)
|
static void process_bcc(int opcode6, int opcode4)
|
{
|
{
|
int Ra, Rb, pred;
|
int Ra, Rb, pred;
|
int fmt;
|
int fmt;
|
int64_t val;
|
int64_t val;
|
int64_t disp, cdisp;
|
int64_t disp, cdisp;
|
char *p1;
|
char *p1;
|
bool ins48 = false;
|
bool ins48 = false;
|
|
|
fmt = GetFPSize();
|
fmt = GetFPSize();
|
pred = 0;
|
pred = 0;
|
p1 = inptr;
|
p1 = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token=='#' && opcode4==0) {
|
if (token=='#' && opcode4==0) {
|
inptr = p1;
|
inptr = p1;
|
process_beqi(0x32,0);
|
process_beqi(0x32,0);
|
return;
|
return;
|
}
|
}
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4);
|
disp = val - (code_address + 4);
|
cdisp = val - (code_address + 2);
|
cdisp = val - (code_address + 2);
|
if (!IsNBit(disp, 12)) {
|
if (!IsNBit(disp, 12)) {
|
error("Branch displacement too large");
|
error("Branch displacement too large");
|
disp = val - (code_address + 6);
|
disp = val - (code_address + 6);
|
ins48 = true;
|
ins48 = true;
|
}
|
}
|
disp >>= 1;
|
disp >>= 1;
|
cdisp >>= 1;
|
cdisp >>= 1;
|
// Check for compressed bnez
|
// Check for compressed bnez
|
if (opcode4 == 1 && Rb == 0 && IsNBit(cdisp,7)) {
|
if (opcode4 == 1 && Rb == 0 && IsNBit(cdisp,7)) {
|
emit_insn(
|
emit_insn(
|
(3 << 14) |
|
(3 << 14) |
|
(((cdisp >> 1) & 0x3f) << 8) |
|
(((cdisp >> 1) & 0x3f) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
((cdisp & 1) << 5) |
|
((cdisp & 1) << 5) |
|
Ra,0,2
|
Ra,0,2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
// compressed beqz
|
// compressed beqz
|
if (opcode4 == 0 && Rb == 0 && IsNBit(cdisp, 7)) {
|
if (opcode4 == 0 && Rb == 0 && IsNBit(cdisp, 7)) {
|
emit_insn(
|
emit_insn(
|
(2 << 14) |
|
(2 << 14) |
|
(((cdisp >> 1) & 0x3f) << 8) |
|
(((cdisp >> 1) & 0x3f) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
((cdisp & 1) << 5) |
|
((cdisp & 1) << 5) |
|
Ra, 0, 2
|
Ra, 0, 2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
if (opcode4 < 0) {
|
if (opcode4 < 0) {
|
opcode4 = -opcode4;
|
opcode4 = -opcode4;
|
emit_insn((disp << 21LL) |
|
emit_insn((disp << 21LL) |
|
(opcode4 << 18) |
|
(opcode4 << 18) |
|
(Ra << 13) |
|
(Ra << 13) |
|
(Rb << 8) |
|
(Rb << 8) |
|
(ins48 << 6) |
|
(ins48 << 6) |
|
opcode6,!expand_flag,ins48 ? 6 : 4
|
opcode6,!expand_flag,ins48 ? 6 : 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn((disp << 21LL) |
|
emit_insn((disp << 21LL) |
|
(opcode4 << 18) |
|
(opcode4 << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(ins48 << 6) |
|
(ins48 << 6) |
|
opcode6, !expand_flag, ins48 ? 6 : 4
|
opcode6, !expand_flag, ins48 ? 6 : 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// dbnz r1,label
|
// dbnz r1,label
|
//
|
//
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_dbnz(int opcode6, int opcode3)
|
static void process_dbnz(int opcode6, int opcode3)
|
{
|
{
|
int Ra, Rc, pred;
|
int Ra, Rc, pred;
|
int64_t val;
|
int64_t val;
|
int64_t disp;
|
int64_t disp;
|
char *p1;
|
char *p1;
|
int sz = 3;
|
int sz = 3;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
pred = 3; // default: statically predict as always taken
|
pred = 3; // default: statically predict as always taken
|
p1 = inptr;
|
p1 = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
if (Rc==-1) {
|
if (Rc==-1) {
|
inptr = p;
|
inptr = p;
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4LL);
|
disp = val - (code_address + 4LL);
|
disp >>= 1LL;
|
disp >>= 1LL;
|
emit_insn(
|
emit_insn(
|
(disp << 21LL) |
|
(disp << 21LL) |
|
((opcode3 & 3) << 19) |
|
((opcode3 & 3) << 19) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,4
|
opcode6,!expand_flag,4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
error("dbnz: target must be a label");
|
error("dbnz: target must be a label");
|
emit_insn(
|
emit_insn(
|
(opcode3 << 19) |
|
(opcode3 << 19) |
|
(0 << 13) |
|
(0 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,4
|
opcode6,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ibne r1,r2,label
|
// ibne r1,r2,label
|
//
|
//
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_ibne(int opcode6, int opcode3)
|
static void process_ibne(int opcode6, int opcode3)
|
{
|
{
|
int Ra, Rb, Rc, pred;
|
int Ra, Rb, Rc, pred;
|
int64_t val;
|
int64_t val;
|
int64_t disp;
|
int64_t disp;
|
char *p1;
|
char *p1;
|
int sz = 3;
|
int sz = 3;
|
char *p;
|
char *p;
|
bool isn48 = false;
|
bool isn48 = false;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
pred = 3; // default: statically predict as always taken
|
pred = 3; // default: statically predict as always taken
|
p1 = inptr;
|
p1 = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
if (Rc==-1) {
|
if (Rc==-1) {
|
inptr = p;
|
inptr = p;
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4LL);
|
disp = val - (code_address + 4LL);
|
disp >>= 1;
|
disp >>= 1;
|
if (!IsNBit(disp, 11)) {
|
if (!IsNBit(disp, 11)) {
|
isn48 = true;
|
isn48 = true;
|
disp = val - (code_address + 6LL);
|
disp = val - (code_address + 6LL);
|
disp >>= 1;
|
disp >>= 1;
|
}
|
}
|
emit_insn((disp << 21LL) |
|
emit_insn((disp << 21LL) |
|
((opcode3 & 3) << 19) |
|
((opcode3 & 3) << 19) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,isn48 ? 6 : 4
|
opcode6,!expand_flag,isn48 ? 6 : 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
error("ibne: target must be a label");
|
error("ibne: target must be a label");
|
emit_insn(
|
emit_insn(
|
(opcode3 << 19) |
|
(opcode3 << 19) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x03,!expand_flag,4
|
0x03,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// bfextu r1,#1,#63,r2
|
// bfextu r1,#1,#63,r2
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_bitfield(int64_t oc)
|
static void process_bitfield(int64_t oc)
|
{
|
{
|
int Ra, Rb, Rc;
|
int Ra, Rb, Rc;
|
int Rt;
|
int Rt;
|
int64_t mb;
|
int64_t mb;
|
int64_t me;
|
int64_t me;
|
int64_t val;
|
int64_t val;
|
int64_t op;
|
int64_t op;
|
int sz = 3;
|
int sz = 3;
|
char *p;
|
char *p;
|
bool gmb, gme, gval;
|
bool gmb, gme, gval;
|
|
|
gmb = gme = gval = false;
|
gmb = gme = gval = false;
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra == -1) {
|
if (Ra == -1) {
|
inptr = p;
|
inptr = p;
|
NextToken();
|
NextToken();
|
mb = expr();
|
mb = expr();
|
gmb = true;
|
gmb = true;
|
}
|
}
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
if (Rb == -1) {
|
if (Rb == -1) {
|
inptr = p;
|
inptr = p;
|
NextToken();
|
NextToken();
|
me = expr();
|
me = expr();
|
gme = true;
|
gme = true;
|
}
|
}
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
if (Rc == -1) {
|
if (Rc == -1) {
|
inptr = p;
|
inptr = p;
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
gval = true;
|
gval = true;
|
}
|
}
|
op =
|
op =
|
(oc << 44LL) |
|
(oc << 44LL) |
|
((gval?1LL:0LL) << 32LL) |
|
((gval?1LL:0LL) << 32LL) |
|
((gme?1LL:0LL) << 31LL) |
|
((gme?1LL:0LL) << 31LL) |
|
((gmb?1:0) << 30) |
|
((gmb?1:0) << 30) |
|
(Rt << 23) |
|
(Rt << 23) |
|
(1 << 6) |
|
(1 << 6) |
|
0x22;
|
0x22;
|
if (gmb)
|
if (gmb)
|
op |= ((mb & 31) << 8) | (((mb >> 5) & 1) << 28);
|
op |= ((mb & 31) << 8) | (((mb >> 5) & 1) << 28);
|
else
|
else
|
op |= (Ra << 8);
|
op |= (Ra << 8);
|
if (gme)
|
if (gme)
|
op |= ((me & 31) << 13) | (((me >> 5) & 1) << 29);
|
op |= ((me & 31) << 13) | (((me >> 5) & 1) << 29);
|
else
|
else
|
op |= (Rb << 13);
|
op |= (Rb << 13);
|
if (gval)
|
if (gval)
|
op |= ((val & 31) << 18) | (((val >> 5) & 0x7ff) << 33LL);
|
op |= ((val & 31) << 18) | (((val >> 5) & 0x7ff) << 33LL);
|
else
|
else
|
op |= (Rc << 18);
|
op |= (Rc << 18);
|
|
|
emit_insn(op, 0, 6);
|
emit_insn(op, 0, 6);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// bra label
|
// bra label
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_bra(int oc)
|
static void process_bra(int oc)
|
{
|
{
|
int Ra = 0, Rb = 0;
|
int Ra = 0, Rb = 0;
|
int64_t val;
|
int64_t val;
|
int64_t disp, cdisp;
|
int64_t disp, cdisp;
|
bool ins48 = false;
|
bool ins48 = false;
|
|
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4LL);
|
disp = val - (code_address + 4LL);
|
cdisp = val - (code_address + 2LL);
|
cdisp = val - (code_address + 2LL);
|
if (!IsNBit(disp, 12)) {
|
if (!IsNBit(disp, 12)) {
|
error("Branch displacement too large");
|
error("Branch displacement too large");
|
disp = val - (code_address + 6LL);
|
disp = val - (code_address + 6LL);
|
ins48 = true;
|
ins48 = true;
|
}
|
}
|
disp >>= 1;
|
disp >>= 1;
|
cdisp >>= 1;
|
cdisp >>= 1;
|
if (cdisp > -512 && cdisp < 512) { // disp+1 accounts for instruction size of 2 not 4
|
if (cdisp > -512 && cdisp < 512) { // disp+1 accounts for instruction size of 2 not 4
|
emit_insn(
|
emit_insn(
|
(7 << 12) |
|
(7 << 12) |
|
(((cdisp >> 6) & 0xf) << 8) |
|
(((cdisp >> 6) & 0xf) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(cdisp & 0x3f), 0, 2
|
(cdisp & 0x3f), 0, 2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn((disp << 21) |
|
emit_insn((disp << 21) |
|
(0 << 18) | // BEQ
|
(0 << 18) | // BEQ
|
(0 << 13) |
|
(0 << 13) |
|
(0 << 8) |
|
(0 << 8) |
|
0x30,!expand_flag,4
|
0x30,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// chk r1,r2,r3,label
|
// chk r1,r2,r3,label
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_chk(int opcode6)
|
static void process_chk(int opcode6)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rb;
|
int Rb;
|
int Rc;
|
int Rc;
|
int64_t val, disp;
|
int64_t val, disp;
|
|
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - code_address;
|
disp = val - code_address;
|
emit_insn(((disp >> 3) & 0x3FF) << 22 |
|
emit_insn(((disp >> 3) & 0x3FF) << 22 |
|
(Rc << 16) |
|
(Rc << 16) |
|
(Rb << 11) |
|
(Rb << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
((disp >> 2) & 1) |
|
((disp >> 2) & 1) |
|
opcode6,!expand_flag,4
|
opcode6,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
|
|
static void process_chki(int opcode6)
|
static void process_chki(int opcode6)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rb;
|
int Rb;
|
int64_t val, disp;
|
int64_t val, disp;
|
|
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
disp = val - code_address;
|
disp = val - code_address;
|
if (val < LB16 || val > 32767LL) {
|
if (val < LB16 || val > 32767LL) {
|
emit_insn((0x8000 << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
|
emit_insn((0x8000 << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
|
emit_insn(val,!expand_flag,2);
|
emit_insn(val,!expand_flag,2);
|
return;
|
return;
|
}
|
}
|
emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
|
emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// fbeq.q fp1,fp0,label
|
// fbeq.q fp1,fp0,label
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_fbcc(int64_t opcode3)
|
static void process_fbcc(int64_t opcode3)
|
{
|
{
|
int Ra, Rb;
|
int Ra, Rb;
|
int64_t val;
|
int64_t val;
|
int64_t disp;
|
int64_t disp;
|
int sz;
|
int sz;
|
bool ins48 = false;
|
bool ins48 = false;
|
|
|
sz = GetFPSize();
|
sz = GetFPSize();
|
Ra = getFPRegister();
|
Ra = getFPRegister();
|
need(',');
|
need(',');
|
Rb = getFPRegister();
|
Rb = getFPRegister();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
|
|
val = expr();
|
val = expr();
|
disp = val - (code_address + 4);
|
disp = val - (code_address + 4);
|
if (!IsNBit(disp, 12)) {
|
if (!IsNBit(disp, 12)) {
|
disp = val - (code_address + 6);
|
disp = val - (code_address + 6);
|
ins48 = true;
|
ins48 = true;
|
}
|
}
|
disp >>= 1;
|
disp >>= 1;
|
emit_insn(
|
emit_insn(
|
(disp << 21LL) |
|
(disp << 21LL) |
|
(opcode3 << 18) |
|
(opcode3 << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
((ins48 ? 1 : 0) << 6) |
|
((ins48 ? 1 : 0) << 6) |
|
0x05, !expand_flag, ins48 ? 6 : 4
|
0x05, !expand_flag, ins48 ? 6 : 4
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_call(int opcode)
|
static void process_call(int opcode)
|
{
|
{
|
int64_t val;
|
int64_t val;
|
int Ra = 0;
|
int Ra = 0;
|
|
|
NextToken();
|
NextToken();
|
if (token == '[')
|
if (token == '[')
|
val = 0;
|
val = 0;
|
else
|
else
|
val = expr();
|
val = expr();
|
if (token=='[') {
|
if (token=='[') {
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(']');
|
need(']');
|
if (Ra==31) {
|
if (Ra==31) {
|
val -= code_address;
|
val -= code_address;
|
}
|
}
|
}
|
}
|
if (val==0) {
|
if (val==0) {
|
if (opcode==0x28) // JMP [Ra]
|
if (opcode==0x28) // JMP [Ra]
|
// jal r0,[Ra]
|
// jal r0,[Ra]
|
emit_insn(
|
emit_insn(
|
(Ra << 6) |
|
(Ra << 6) |
|
0x18,!expand_flag,4
|
0x18,!expand_flag,4
|
);
|
);
|
else
|
else
|
// jal lr,[Ra] - call [Ra]
|
// jal lr,[Ra] - call [Ra]
|
//emit_insn(
|
//emit_insn(
|
// (29 << 13) |
|
// (29 << 13) |
|
// (Ra << 8) |
|
// (Ra << 8) |
|
// 0x18,!expand_flag,4
|
// 0x18,!expand_flag,4
|
//);
|
//);
|
emit_insn(
|
emit_insn(
|
(2 << 12) |
|
(2 << 12) |
|
(((29 >> 1) & 0xf) << 8) |
|
(((29 >> 1) & 0xf) << 8) |
|
(3 << 6) |
|
(3 << 6) |
|
((29 & 1) << 5) |
|
((29 & 1) << 5) |
|
Ra,0,2
|
Ra,0,2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
if (code_bits > 27 && !IsNBit(val,40)) {
|
if (code_bits > 27 && !IsNBit(val,40)) {
|
LoadConstant(val,23);
|
LoadConstant(val,23);
|
if (Ra!=0) {
|
if (Ra!=0) {
|
// add r23,r23,Ra
|
// add r23,r23,Ra
|
emit_insn(
|
emit_insn(
|
(0x04 << 26) |
|
(0x04 << 26) |
|
(23 << 18) |
|
(23 << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02,!expand_flag,4
|
0x02,!expand_flag,4
|
);
|
);
|
}
|
}
|
if (opcode==0x28) // JMP
|
if (opcode==0x28) // JMP
|
// jal r0,[r23]
|
// jal r0,[r23]
|
emit_insn(
|
emit_insn(
|
(23 << 8) |
|
(23 << 8) |
|
0x18,!expand_flag,4
|
0x18,!expand_flag,4
|
);
|
);
|
else
|
else
|
// jal lr,[r23] - call [r23]
|
// jal lr,[r23] - call [r23]
|
emit_insn(
|
emit_insn(
|
(29 << 13) |
|
(29 << 13) |
|
(23 << 8) |
|
(23 << 8) |
|
0x18,!expand_flag,4
|
0x18,!expand_flag,4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 24)) {
|
if (!IsNBit(val, 24)) {
|
emit_insn(
|
emit_insn(
|
((((val >> 1) & 0xFFFFFFFFFFLL)) << 8) |
|
((((val >> 1) & 0xFFFFFFFFFFLL)) << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode, !expand_flag, 4
|
opcode, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((((val >> 1) & 0xFFFFFFLL)) << 8) |
|
((((val >> 1) & 0xFFFFFFLL)) << 8) |
|
opcode,!expand_flag,4
|
opcode,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
static void process_iret(int op)
|
static void process_iret(int op)
|
{
|
{
|
int64_t val = 0;
|
int64_t val = 0;
|
|
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
val = expr();
|
val = expr();
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((val & 0x3F) << 18) |
|
((val & 0x3F) << 18) |
|
(0 << 12) |
|
(0 << 12) |
|
(0 << 6) |
|
(0 << 6) |
|
op,!expand_flag,5
|
op,!expand_flag,5
|
);
|
);
|
}
|
}
|
|
|
static void process_ret()
|
static void process_ret()
|
{
|
{
|
int64_t val = 0;
|
int64_t val = 0;
|
bool ins48 = false;
|
bool ins48 = false;
|
|
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
val = expr();
|
val = expr();
|
}
|
}
|
// Compress ?
|
// Compress ?
|
if (val >= 0 && val < 256) {
|
if (val >= 0 && val < 256) {
|
emit_insn(
|
emit_insn(
|
(2 << 12) |
|
(2 << 12) |
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
(((val >> 3) & 1) << 5),
|
(((val >> 3) & 1) << 5),
|
0, 2
|
0, 2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
// If too large a constant, do the SP adjusment directly.
|
// If too large a constant, do the SP adjusment directly.
|
if (!IsNBit(val,30)) {
|
if (!IsNBit(val,30)) {
|
LoadConstant(val,23);
|
LoadConstant(val,23);
|
// add.w r63,r63,r23
|
// add.w r63,r63,r23
|
emit_insn(
|
emit_insn(
|
(0x04LL << 26LL) |
|
(0x04LL << 26LL) |
|
(3 << 23) |
|
(3 << 23) |
|
(regSP << 18) |
|
(regSP << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(regSP << 8) |
|
(regSP << 8) |
|
0x02,!expand_flag,4
|
0x02,!expand_flag,4
|
);
|
);
|
val = 0;
|
val = 0;
|
}
|
}
|
ins48 = !IsNBit(val, 14);
|
ins48 = !IsNBit(val, 14);
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(regLR << 13) |
|
(regLR << 13) |
|
(regSP << 8) |
|
(regSP << 8) |
|
(ins48 << 6) |
|
(ins48 << 6) |
|
0x29,!expand_flag, ins48 ? 6 : 4
|
0x29,!expand_flag, ins48 ? 6 : 4
|
);
|
);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// inc -8[bp],#1
|
// inc -8[bp],#1
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_inc(int64_t oc)
|
static void process_inc(int64_t oc)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rb;
|
int Rb;
|
int Sc;
|
int Sc;
|
int64_t incamt;
|
int64_t incamt;
|
int64_t disp;
|
int64_t disp;
|
char *p;
|
char *p;
|
int fixup = 5;
|
int fixup = 5;
|
int neg = 0;
|
int neg = 0;
|
|
|
if (oc == 0x25) neg = 1;
|
if (oc == 0x25) neg = 1;
|
NextToken();
|
NextToken();
|
p = inptr;
|
p = inptr;
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
incamt = 1;
|
incamt = 1;
|
if (token==']')
|
if (token==']')
|
NextToken();
|
NextToken();
|
if (token==',') {
|
if (token==',') {
|
NextToken();
|
NextToken();
|
incamt = expr();
|
incamt = expr();
|
prevToken();
|
prevToken();
|
}
|
}
|
if (neg) incamt = -incamt;
|
if (neg) incamt = -incamt;
|
if (Rb >= 0) {
|
if (Rb >= 0) {
|
if (disp != 0)
|
if (disp != 0)
|
error("displacement not allowed with indexed addressing");
|
error("displacement not allowed with indexed addressing");
|
oc = 0x1A; // INCX
|
oc = 0x1A; // INCX
|
// ToDo: fix this
|
// ToDo: fix this
|
emit_insn(
|
emit_insn(
|
(oc << 26LL) |
|
(oc << 26LL) |
|
(0 << 23) | // Sc = 0
|
(0 << 23) | // Sc = 0
|
(incamt << 18) |
|
(incamt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16, !expand_flag, 4
|
0x16, !expand_flag, 4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
oc = 0x1A; // INC
|
oc = 0x1A; // INC
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
incamt &= 31;
|
incamt &= 31;
|
if (!IsNBit(disp, 30)) {
|
if (!IsNBit(disp, 30)) {
|
LoadConstant(disp, 23);
|
LoadConstant(disp, 23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
emit_insn(
|
emit_insn(
|
(oc << 26LL) |
|
(oc << 26LL) |
|
(0 << 23) | // Sc = 0
|
(0 << 23) | // Sc = 0
|
(incamt << 18) |
|
(incamt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16, !expand_flag, 4);
|
0x16, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(disp, 14)) {
|
if (!IsNBit(disp, 14)) {
|
emit_insn(
|
emit_insn(
|
(disp << 18LL) |
|
(disp << 18LL) |
|
(incamt << 13) |
|
(incamt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
oc, !expand_flag, 6);
|
oc, !expand_flag, 6);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(disp << 18LL) |
|
(disp << 18LL) |
|
(incamt << 13) |
|
(incamt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
oc, !expand_flag, 4);
|
oc, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_brk()
|
static void process_brk()
|
{
|
{
|
int64_t val;
|
int64_t val;
|
int inc = 1;
|
int inc = 1;
|
int Ra = -1;
|
int Ra = -1;
|
|
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra == -1) {
|
if (Ra == -1) {
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
NextToken();
|
NextToken();
|
if (token == ',') {
|
if (token == ',') {
|
inc = (int)expr();
|
inc = (int)expr();
|
}
|
}
|
else
|
else
|
prevToken();
|
prevToken();
|
emit_insn(
|
emit_insn(
|
((inc & 0x1f) << 19) |
|
((inc & 0x1f) << 19) |
|
((val & 0x1FFLL) << 6) |
|
((val & 0x1FFLL) << 6) |
|
0x00, !expand_flag, 5
|
0x00, !expand_flag, 5
|
);
|
);
|
return;
|
return;
|
}
|
}
|
NextToken();
|
NextToken();
|
if (token == ',') {
|
if (token == ',') {
|
inc = (int)expr();
|
inc = (int)expr();
|
}
|
}
|
else
|
else
|
prevToken();
|
prevToken();
|
emit_insn(
|
emit_insn(
|
((inc & 0x1f) << 19) |
|
((inc & 0x1f) << 19) |
|
(1 << 15) |
|
(1 << 15) |
|
((Ra & 0x3FLL) << 6) |
|
((Ra & 0x3FLL) << 6) |
|
0x00, !expand_flag, 5
|
0x00, !expand_flag, 5
|
);
|
);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void GetIndexScale(int *sc)
|
static void GetIndexScale(int *sc)
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
prevToken();
|
prevToken();
|
switch(val) {
|
switch(val) {
|
case 0: *sc = 0; break;
|
case 0: *sc = 0; break;
|
case 1: *sc = 0; break;
|
case 1: *sc = 0; break;
|
case 2: *sc = 1; break;
|
case 2: *sc = 1; break;
|
case 4: *sc = 2; break;
|
case 4: *sc = 2; break;
|
case 8: *sc = 3; break;
|
case 8: *sc = 3; break;
|
default: printf("Illegal scaling factor.\r\n");
|
default: printf("Illegal scaling factor.\r\n");
|
}
|
}
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// expr
|
// expr
|
// expr[Reg]
|
// expr[Reg]
|
// [Reg]
|
// [Reg]
|
// [Reg+Reg]
|
// [Reg+Reg]
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc)
|
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc)
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
// chech params
|
// chech params
|
if (disp == (int64_t *)NULL)
|
if (disp == (int64_t *)NULL)
|
return;
|
return;
|
if (regA == (int *)NULL)
|
if (regA == (int *)NULL)
|
return;
|
return;
|
if (regB == (int *)NULL)
|
if (regB == (int *)NULL)
|
return;
|
return;
|
if (Sc == (int *)NULL)
|
if (Sc == (int *)NULL)
|
return;
|
return;
|
|
|
*disp = 0;
|
*disp = 0;
|
*regA = -1;
|
*regA = -1;
|
*regB = -1;
|
*regB = -1;
|
*Sc = 0;
|
*Sc = 0;
|
if (token!='[') {;
|
if (token!='[') {;
|
val = expr();
|
val = expr();
|
*disp = val;
|
*disp = val;
|
}
|
}
|
if (token=='[') {
|
if (token=='[') {
|
*regA = getRegisterX();
|
*regA = getRegisterX();
|
if (*regA == -1) {
|
if (*regA == -1) {
|
printf("expecting a register\r\n");
|
printf("expecting a register\r\n");
|
}
|
}
|
if (token=='+') {
|
if (token=='+') {
|
*regB = getRegisterX();
|
*regB = getRegisterX();
|
if (*regB == -1) {
|
if (*regB == -1) {
|
printf("expecting a register\r\n");
|
printf("expecting a register\r\n");
|
}
|
}
|
if (token=='*') {
|
if (token=='*') {
|
GetIndexScale(Sc);
|
GetIndexScale(Sc);
|
}
|
}
|
}
|
}
|
need(']');
|
need(']');
|
}
|
}
|
}
|
}
|
|
|
static void mem_voperand(int64_t *disp, int *regA, int *regB)
|
static void mem_voperand(int64_t *disp, int *regA, int *regB)
|
{
|
{
|
int64_t val;
|
int64_t val;
|
|
|
// chech params
|
// chech params
|
if (disp == (int64_t *)NULL)
|
if (disp == (int64_t *)NULL)
|
return;
|
return;
|
if (regA == (int *)NULL)
|
if (regA == (int *)NULL)
|
return;
|
return;
|
|
|
*disp = 0;
|
*disp = 0;
|
*regA = -1;
|
*regA = -1;
|
*regB = -1;
|
*regB = -1;
|
if (token!='[') {;
|
if (token!='[') {;
|
val = expr();
|
val = expr();
|
*disp = val;
|
*disp = val;
|
}
|
}
|
if (token=='[') {
|
if (token=='[') {
|
*regA = getRegisterX();
|
*regA = getRegisterX();
|
if (*regA == -1) {
|
if (*regA == -1) {
|
printf("expecting a register\r\n");
|
printf("expecting a register\r\n");
|
}
|
}
|
if (token=='+') {
|
if (token=='+') {
|
*regB = getVecRegister();
|
*regB = getVecRegister();
|
if (*regB == -1) {
|
if (*regB == -1) {
|
printf("expecting a vector register: %d\r\n", lineno);
|
printf("expecting a vector register: %d\r\n", lineno);
|
}
|
}
|
}
|
}
|
need(']');
|
need(']');
|
}
|
}
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// If the displacement is too large the instruction is converted to an
|
// If the displacement is too large the instruction is converted to an
|
// indexed form and the displacement loaded into a second register.
|
// indexed form and the displacement loaded into a second register.
|
//
|
//
|
// So
|
// So
|
// sw r2,$12345678[r2]
|
// sw r2,$12345678[r2]
|
// Becomes:
|
// Becomes:
|
// ori r23,r0,#$5678
|
// ori r23,r0,#$5678
|
// orq1 r23,#$1234
|
// orq1 r23,#$1234
|
// sw r2,[r2+r23]
|
// sw r2,[r2+r23]
|
//
|
//
|
// sw disp[r1],r2
|
// sw disp[r1],r2
|
// sw [r1+r2],r3
|
// sw [r1+r2],r3
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_store(int64_t opcode6, int sz)
|
static void process_store(int64_t opcode6, int sz)
|
{
|
{
|
int Ra,Rb;
|
int Ra,Rb;
|
int Rs;
|
int Rs;
|
int Sc;
|
int Sc;
|
int64_t disp,val;
|
int64_t disp,val;
|
int64_t aq = 0, rl = 0;
|
int64_t aq = 0, rl = 0;
|
int ar;
|
int ar;
|
|
|
GetArBits(&aq, &rl);
|
GetArBits(&aq, &rl);
|
ar = (int)((aq << 1LL) | rl);
|
ar = (int)((aq << 1LL) | rl);
|
Rs = getRegisterX();
|
Rs = getRegisterX();
|
if (Rs < 0) {
|
if (Rs < 0) {
|
printf("Expecting a source register (%d).\r\n", lineno);
|
printf("Expecting a source register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",inptr);
|
printf("Line:%.60s\r\n",inptr);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
switch (sz) {
|
switch (sz) {
|
case 1: opcode6 = 0x24; break; // SCX
|
case 1: opcode6 = 0x24; break; // SCX
|
case 2: opcode6 = 0x14; break; // SHX
|
case 2: opcode6 = 0x14; break; // SHX
|
case 4: opcode6 = 0x16; break; // SWX
|
case 4: opcode6 = 0x16; break; // SWX
|
default:;
|
default:;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26LL) |
|
(opcode6 << 26LL) |
|
(Sc << 23) |
|
(Sc << 23) |
|
(Rs << 18) |
|
(Rs << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (Ra == 55)
|
if (Ra == 55)
|
val -= program_address;
|
val -= program_address;
|
if (sz == 4 && Ra == regSP) {
|
if (sz == 4 && Ra == regSP) {
|
if ((val & 7) == 0) {
|
if ((val & 7) == 0) {
|
if (val >= -128 && val < 128) {
|
if (val >= -128 && val < 128) {
|
emit_insn(
|
emit_insn(
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(9 << 12) |
|
(9 << 12) |
|
(3 << 6) |
|
(3 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
Rs, 0, 2
|
Rs, 0, 2
|
);
|
);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (sz == 4 && Ra == regFP) {
|
if (sz == 4 && Ra == regFP) {
|
if ((val & 7) == 0) {
|
if ((val & 7) == 0) {
|
if (val >= -128 && val < 128) {
|
if (val >= -128 && val < 128) {
|
emit_insn(
|
emit_insn(
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(11 << 12) |
|
(11 << 12) |
|
(3 << 6) |
|
(3 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
Rs, 0, 2
|
Rs, 0, 2
|
);
|
);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (!IsNBit(val,30)) {
|
if (!IsNBit(val,30)) {
|
LoadConstant(val,23);
|
LoadConstant(val,23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
switch (sz) {
|
switch (sz) {
|
case 1: opcode6 = 0x24; break;
|
case 1: opcode6 = 0x24; break;
|
case 2: opcode6 = 0x14; break;
|
case 2: opcode6 = 0x14; break;
|
case 4: opcode6 = 0x16; break;
|
case 4: opcode6 = 0x16; break;
|
default: opcode6 = 0x15;
|
default: opcode6 = 0x15;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26LL) |
|
(opcode6 << 26LL) |
|
(0 << 23) | // Sc
|
(0 << 23) | // Sc
|
(Rs << 18) |
|
(Rs << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02,!expand_flag,4);
|
0x16,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
((val|sz) << 18) |
|
((val|sz) << 18) |
|
(Rs << 13) |
|
(Rs << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag, 6);
|
opcode6, !expand_flag, 6);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((val|sz) << 18) |
|
((val|sz) << 18) |
|
(Rs << 13) |
|
(Rs << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
/*
|
/*
|
static void process_storepair(int64_t opcode6)
|
static void process_storepair(int64_t opcode6)
|
{
|
{
|
int Ra, Rb;
|
int Ra, Rb;
|
int Rs, Rs2;
|
int Rs, Rs2;
|
int Sc;
|
int Sc;
|
int64_t disp, val;
|
int64_t disp, val;
|
int64_t aq = 0, rl = 0;
|
int64_t aq = 0, rl = 0;
|
int ar;
|
int ar;
|
|
|
GetArBits(&aq, &rl);
|
GetArBits(&aq, &rl);
|
ar = (int)((aq << 1LL) | rl);
|
ar = (int)((aq << 1LL) | rl);
|
Rs = getRegisterX();
|
Rs = getRegisterX();
|
if (Rs < 0) {
|
if (Rs < 0) {
|
printf("Expecting a source register (%d).\r\n", lineno);
|
printf("Expecting a source register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n", inptr);
|
printf("Line:%.60s\r\n", inptr);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
Rs2 = getRegisterX();
|
Rs2 = getRegisterX();
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
emit_insn(
|
emit_insn(
|
(opcode6 << 34LL) |
|
(opcode6 << 34LL) |
|
(ar << 26) |
|
(ar << 26) |
|
(Sc << 24) |
|
(Sc << 24) |
|
(Rs << 18) |
|
(Rs << 18) |
|
(Rb << 12) |
|
(Rb << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x02, !expand_flag, 5);
|
0x02, !expand_flag, 5);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (Ra == 55)
|
if (Ra == 55)
|
val -= program_address;
|
val -= program_address;
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
LoadConstant(val, 52);
|
LoadConstant(val, 52);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
emit_insn(
|
emit_insn(
|
(opcode6 << 34LL) |
|
(opcode6 << 34LL) |
|
(ar << 26) |
|
(ar << 26) |
|
(0 << 24) | // Sc
|
(0 << 24) | // Sc
|
(Rs << 18) |
|
(Rs << 18) |
|
(52 << 12) |
|
(52 << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x02, !expand_flag, 5);
|
0x02, !expand_flag, 5);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 26LL) |
|
(val << 26LL) |
|
(ar << 24) |
|
(ar << 24) |
|
(Rs2 << 18) |
|
(Rs2 << 18) |
|
(Rs << 12) |
|
(Rs << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
opcode6, !expand_flag, 5, true);
|
opcode6, !expand_flag, 5, true);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
*/
|
*/
|
static void process_sv(int64_t opcode6)
|
static void process_sv(int64_t opcode6)
|
{
|
{
|
int Ra,Vb;
|
int Ra,Vb;
|
int Vs;
|
int Vs;
|
int64_t disp,val;
|
int64_t disp,val;
|
int64_t aq = 0, rl = 0;
|
int64_t aq = 0, rl = 0;
|
int ar = 0;
|
int ar = 0;
|
|
|
GetArBits(&aq, &rl);
|
GetArBits(&aq, &rl);
|
ar = (int)((aq << 1LL) | rl);
|
ar = (int)((aq << 1LL) | rl);
|
Vs = getVecRegister();
|
Vs = getVecRegister();
|
if (Vs < 0 || Vs > 63) {
|
if (Vs < 0 || Vs > 63) {
|
printf("Expecting a vector source register (%d).\r\n", lineno);
|
printf("Expecting a vector source register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",inptr);
|
printf("Line:%.60s\r\n",inptr);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_voperand(&disp, &Ra, &Vb);
|
mem_voperand(&disp, &Ra, &Vb);
|
if (Ra > 0 && Vb > 0) {
|
if (Ra > 0 && Vb > 0) {
|
emit_insn(
|
emit_insn(
|
(opcode6 << 34LL) |
|
(opcode6 << 34LL) |
|
(ar << 26) |
|
(ar << 26) |
|
(Vs << 18) |
|
(Vs << 18) |
|
(Vb << 12) |
|
(Vb << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x02,!expand_flag,5);
|
0x02,!expand_flag,5);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
//if (val < -32768 || val > 32767)
|
//if (val < -32768 || val > 32767)
|
// printf("SV displacement too large: %d\r\n", lineno);
|
// printf("SV displacement too large: %d\r\n", lineno);
|
if (!IsNBit(val, 20)) {
|
if (!IsNBit(val, 20)) {
|
LoadConstant(val, 52);
|
LoadConstant(val, 52);
|
// ToDo: store with indexed addressing
|
// ToDo: store with indexed addressing
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 20) |
|
(val << 20) |
|
(ar << 18) |
|
(ar << 18) |
|
(Vs << 12) |
|
(Vs << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
opcode6,!expand_flag,5);
|
opcode6,!expand_flag,5);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_ldi()
|
static void process_ldi()
|
{
|
{
|
int Ra = 0;
|
int Ra = 0;
|
int Rt;
|
int Rt;
|
int64_t val;
|
int64_t val;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p=='.')
|
if (*p=='.')
|
getSz(&sz);
|
getSz(&sz);
|
sz &= 3;
|
sz &= 3;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
expect(',');
|
expect(',');
|
val = expr();
|
val = expr();
|
if (IsNBit(val, 5) && Rt != 0) {
|
if (IsNBit(val, 5) && Rt != 0) {
|
emit_insn(
|
emit_insn(
|
(1 << 12) |
|
(1 << 12) |
|
(((val >> 1) & 0x0f) << 8)|
|
(((val >> 1) & 0x0f) << 8)|
|
(2 << 6) |
|
(2 << 6) |
|
((val & 1) << 5) |
|
((val & 1) << 5) |
|
Rt,
|
Rt,
|
!expand_flag,2
|
!expand_flag,2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
if (IsNBit(val, 14)) {
|
if (IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(0 << 8) | // ADDI
|
(0 << 8) | // ADDI
|
0x04, !expand_flag, 4);
|
0x04, !expand_flag, 4);
|
return;
|
return;
|
}
|
}
|
if (IsNBit(val, 30)) {
|
if (IsNBit(val, 30)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(0 << 8) | // ADDI
|
(0 << 8) | // ADDI
|
(1 << 6) |
|
(1 << 6) |
|
0x04, !expand_flag, 6);
|
0x04, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
if (IsNBit(val, 49)) {
|
if (IsNBit(val, 49)) {
|
emit_insn(
|
emit_insn(
|
((val >> 30LL) << 13LL) |
|
((val >> 30LL) << 13LL) |
|
(Rt << 8) |
|
(Rt << 8) |
|
(0 << 6) |
|
(0 << 6) |
|
0x27, !expand_flag, 4
|
0x27, !expand_flag, 4
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(0 << 8) | // ORI
|
(0 << 8) | // ORI
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6);
|
0x09, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
// 64 bit constant
|
// 64 bit constant
|
emit_insn(
|
emit_insn(
|
((val >> 30LL) << 13LL) |
|
((val >> 30LL) << 13LL) |
|
(Rt << 8) |
|
(Rt << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
0x27, !expand_flag, 6
|
0x27, !expand_flag, 6
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(0 << 8) | // ORI
|
(0 << 8) | // ORI
|
(1 << 6) |
|
(1 << 6) |
|
0x09, !expand_flag, 6);
|
0x09, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// link #-40
|
// link #-40
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// lw r1,disp[r2]
|
// lw r1,disp[r2]
|
// lw r1,[r2+r3]
|
// lw r1,[r2+r3]
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_load(int64_t opcode6, int sz)
|
static void process_load(int64_t opcode6, int sz)
|
{
|
{
|
int Ra,Rb;
|
int Ra,Rb;
|
int Rt;
|
int Rt;
|
int Sc;
|
int Sc;
|
char *p;
|
char *p;
|
int64_t disp;
|
int64_t disp;
|
int64_t val;
|
int64_t val;
|
int64_t aq = 0, rl = 0;
|
int64_t aq = 0, rl = 0;
|
int ar;
|
int ar;
|
int fixup = 5;
|
int fixup = 5;
|
|
|
GetArBits(&aq, &rl);
|
GetArBits(&aq, &rl);
|
ar = (int)((aq << 1LL) | rl);
|
ar = (int)((aq << 1LL) | rl);
|
p = inptr;
|
p = inptr;
|
if (opcode6==0x26)
|
if (opcode6==0x26)
|
Rt = getVecRegister();
|
Rt = getVecRegister();
|
else
|
else
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
if (Rt < 0) {
|
if (Rt < 0) {
|
printf("Expecting a target register (%d).\r\n", lineno);
|
printf("Expecting a target register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",p);
|
printf("Line:%.60s\r\n",p);
|
ScanToEOL();
|
ScanToEOL();
|
inptr-=2;
|
inptr-=2;
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
// Trap LEA, convert to LEAX opcode
|
// Trap LEA, convert to LEAX opcode
|
if (opcode6==0x04) // ADD is really LEA
|
if (opcode6==0x04) // ADD is really LEA
|
opcode6 = 0x18;
|
opcode6 = 0x18;
|
else {
|
else {
|
switch (sz) {
|
switch (sz) {
|
case -1: opcode6 = 0x21; break; // LCUX
|
case -1: opcode6 = 0x21; break; // LCUX
|
case 1: opcode6 = 0x20; break; // LCX
|
case 1: opcode6 = 0x20; break; // LCX
|
case -2: opcode6 = 0x11; break; // LHUX
|
case -2: opcode6 = 0x11; break; // LHUX
|
case 2: opcode6 = 0x10; break; // LHX
|
case 2: opcode6 = 0x10; break; // LHX
|
case 4: opcode6 = 0x12; break; // LWX
|
case 4: opcode6 = 0x12; break; // LWX
|
}
|
}
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26LL) |
|
(opcode6 << 26LL) |
|
(Sc << 23) |
|
(Sc << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (Ra == 55)
|
if (Ra == 55)
|
val -= program_address;
|
val -= program_address;
|
if (sz == 4 && Ra == regSP) {
|
if (sz == 4 && Ra == regSP) {
|
if ((val & 7) == 0) {
|
if ((val & 7) == 0) {
|
if (val >= -128 && val < 128) {
|
if (val >= -128 && val < 128) {
|
emit_insn(
|
emit_insn(
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(5 << 12) |
|
(5 << 12) |
|
(3 << 6) |
|
(3 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
Rt, 0, 2
|
Rt, 0, 2
|
);
|
);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (sz == 4 && Ra == regFP) {
|
if (sz == 4 && Ra == regFP) {
|
if ((val & 7) == 0) {
|
if ((val & 7) == 0) {
|
if (val >= -128 && val < 128) {
|
if (val >= -128 && val < 128) {
|
emit_insn(
|
emit_insn(
|
(((val >> 4) & 0x0F) << 8) |
|
(((val >> 4) & 0x0F) << 8) |
|
(7 << 12) |
|
(7 << 12) |
|
(3 << 6) |
|
(3 << 6) |
|
(((val >> 3) & 0x1) << 5) |
|
(((val >> 3) & 0x1) << 5) |
|
Rt, 0, 2
|
Rt, 0, 2
|
);
|
);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
}
|
}
|
}
|
}
|
if (!IsNBit(val, 30)) {
|
if (!IsNBit(val, 30)) {
|
LoadConstant(val, 23);
|
LoadConstant(val, 23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
switch (sz) {
|
switch (sz) {
|
case -1: opcode6 = 0x21; // LCUX
|
case -1: opcode6 = 0x21; // LCUX
|
case 1: opcode6 = 0x20; // LCX
|
case 1: opcode6 = 0x20; // LCX
|
case -2: opcode6 = 0x11; // LHUX
|
case -2: opcode6 = 0x11; // LHUX
|
case 2: opcode6 = 0x10; // LHX
|
case 2: opcode6 = 0x10; // LHX
|
case 4: opcode6 = 0x12; // LWX
|
case 4: opcode6 = 0x12; // LWX
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26LL) |
|
(opcode6 << 26LL) |
|
(0 << 23) | // Sc = 0
|
(0 << 23) | // Sc = 0
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02,!expand_flag,4);
|
0x16,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
((val|abs(sz)) << 18LL) |
|
((val|abs(sz)) << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag, 6);
|
opcode6, !expand_flag, 6);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((val|abs(sz)) << 18LL) |
|
((val|abs(sz)) << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
static void process_cache(int opcode6)
|
static void process_cache(int opcode6)
|
{
|
{
|
int Ra,Rb;
|
int Ra,Rb;
|
int Sc;
|
int Sc;
|
char *p;
|
char *p;
|
int64_t disp;
|
int64_t disp;
|
int64_t val;
|
int64_t val;
|
int fixup = 5;
|
int fixup = 5;
|
int cmd;
|
int cmd;
|
|
|
p = inptr;
|
p = inptr;
|
NextToken();
|
NextToken();
|
cmd = (int)expr() & 0x1f;
|
cmd = (int)expr() & 0x1f;
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26) |
|
(opcode6 << 26) |
|
(Sc << 21) |
|
(Sc << 21) |
|
(cmd << 16) |
|
(cmd << 16) |
|
(Rb << 11) |
|
(Rb << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (!IsNBit(val,30)) {
|
if (!IsNBit(val,30)) {
|
LoadConstant(val,23);
|
LoadConstant(val,23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26) |
|
(opcode6 << 26) |
|
(cmd << 18) |
|
(cmd << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(cmd << 13) |
|
(cmd << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag, 6);
|
opcode6, !expand_flag, 6);
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 18) |
|
(val << 18) |
|
(cmd << 13) |
|
(cmd << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// lw r1,disp[r2]
|
// lw r1,disp[r2]
|
// lw r1,[r2+r3]
|
// lw r1,[r2+r3]
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void ProcessLoadVolatile(int64_t opcode, int sz)
|
static void ProcessLoadVolatile(int64_t opcode, int sz)
|
{
|
{
|
int Ra,Rb;
|
int Ra,Rb;
|
int Rt;
|
int Rt;
|
int Sc;
|
int Sc;
|
char *p;
|
char *p;
|
int64_t disp;
|
int64_t disp;
|
int64_t val;
|
int64_t val;
|
int fixup = 5;
|
int fixup = 5;
|
|
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
if (Rt < 0) {
|
if (Rt < 0) {
|
printf("Expecting a target register (%d).\r\n", lineno);
|
printf("Expecting a target register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",p);
|
printf("Line:%.60s\r\n",p);
|
ScanToEOL();
|
ScanToEOL();
|
inptr-=2;
|
inptr-=2;
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
switch (sz) {
|
switch (sz) {
|
case -1: opcode = 0x01; // LVBUX
|
case -1: opcode = 0x01; // LVBUX
|
case 1: opcode = 0x00; // LVBX
|
case 1: opcode = 0x00; // LVBX
|
case -2: opcode = 0x03; // LVCUX
|
case -2: opcode = 0x03; // LVCUX
|
case 2: opcode = 0x02; // LVCX
|
case 2: opcode = 0x02; // LVCX
|
case -4: opcode = 0x05; // LVHUX
|
case -4: opcode = 0x05; // LVHUX
|
case 4: opcode = 0x04; // LVHX
|
case 4: opcode = 0x04; // LVHX
|
case 8: opcode = 0x06; // LVWX
|
case 8: opcode = 0x06; // LVWX
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode << 26) |
|
(opcode << 26) |
|
(Sc << 23) |
|
(Sc << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (!IsNBit(val, 30)) {
|
if (!IsNBit(val, 30)) {
|
LoadConstant(val, 23);
|
LoadConstant(val, 23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
switch (sz) {
|
switch (sz) {
|
case -1: opcode = 0x01; // LVBUX
|
case -1: opcode = 0x01; // LVBUX
|
case 1: opcode = 0x00; // LVBX
|
case 1: opcode = 0x00; // LVBX
|
case -2: opcode = 0x03; // LVCUX
|
case -2: opcode = 0x03; // LVCUX
|
case 2: opcode = 0x02; // LVCX
|
case 2: opcode = 0x02; // LVCX
|
case -4: opcode = 0x05; // LVHUX
|
case -4: opcode = 0x05; // LVHUX
|
case 4: opcode = 0x04; // LVHX
|
case 4: opcode = 0x04; // LVHX
|
case 8: opcode = 0x06; // LVWX
|
case 8: opcode = 0x06; // LVWX
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(opcode << 26LL) |
|
(opcode << 26LL) |
|
(0 << 23) | // Sc = 0
|
(0 << 23) | // Sc = 0
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02, !expand_flag, 4);
|
0x02, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
((val | abs(sz)) << 18LL) |
|
((val | abs(sz)) << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode, !expand_flag, 6);
|
opcode, !expand_flag, 6);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
((val | abs(sz)) << 18LL) |
|
((val | abs(sz)) << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode, !expand_flag, 4);
|
opcode, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
static void process_lv(int opcode6)
|
static void process_lv(int opcode6)
|
{
|
{
|
int Ra,Vb;
|
int Ra,Vb;
|
int Vt;
|
int Vt;
|
char *p;
|
char *p;
|
int64_t disp;
|
int64_t disp;
|
int64_t val;
|
int64_t val;
|
int fixup = 5;
|
int fixup = 5;
|
|
|
p = inptr;
|
p = inptr;
|
Vt = getVecRegister();
|
Vt = getVecRegister();
|
if (Vt < 0) {
|
if (Vt < 0) {
|
printf("Expecting a vector target register (%d).\r\n", lineno);
|
printf("Expecting a vector target register (%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",p);
|
printf("Line:%.60s\r\n",p);
|
ScanToEOL();
|
ScanToEOL();
|
inptr-=2;
|
inptr-=2;
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_voperand(&disp, &Ra, &Vb);
|
mem_voperand(&disp, &Ra, &Vb);
|
if (Ra > 0 && Vb > 0) {
|
if (Ra > 0 && Vb > 0) {
|
emit_insn(
|
emit_insn(
|
(opcode6 << 26) |
|
(opcode6 << 26) |
|
(Vt << 16) |
|
(Vt << 16) |
|
(Vb << 11) |
|
(Vb << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x02,!expand_flag,4);
|
0x02,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
//if (val < -32768 || val > 32767)
|
//if (val < -32768 || val > 32767)
|
// printf("LV displacement too large: %d\r\n", lineno);
|
// printf("LV displacement too large: %d\r\n", lineno);
|
if (val >= -32768 && val < 32768) {
|
if (val >= -32768 && val < 32768) {
|
emit_insn(
|
emit_insn(
|
(val << 16) |
|
(val << 16) |
|
(Vt << 11) |
|
(Vt << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
LoadConstant(val,23);
|
LoadConstant(val,23);
|
// add r23,r23,ra
|
// add r23,r23,ra
|
if (Ra != 0)
|
if (Ra != 0)
|
emit_insn(
|
emit_insn(
|
(0x04 << 26) |
|
(0x04 << 26) |
|
(3 << 21) |
|
(3 << 21) |
|
(23 << 16) |
|
(23 << 16) |
|
(23 << 11) |
|
(23 << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x02,!expand_flag,4
|
0x02,!expand_flag,4
|
);
|
);
|
emit_insn(
|
emit_insn(
|
(Vt << 11) |
|
(Vt << 11) |
|
(23 << 6) |
|
(23 << 6) |
|
opcode6,!expand_flag,4);
|
opcode6,!expand_flag,4);
|
ScanToEOL();
|
ScanToEOL();
|
}
|
}
|
|
|
static void process_lsfloat(int64_t opcode6, int64_t opcode3)
|
static void process_lsfloat(int64_t opcode6, int64_t opcode3)
|
{
|
{
|
int Ra,Rb;
|
int Ra,Rb;
|
int Rt;
|
int Rt;
|
int Sc;
|
int Sc;
|
char *p;
|
char *p;
|
int64_t disp;
|
int64_t disp;
|
int64_t val;
|
int64_t val;
|
int fixup = 5;
|
int fixup = 5;
|
|
|
int sz;
|
int sz;
|
int rm;
|
int rm;
|
|
|
rm = 0;
|
rm = 0;
|
sz = GetFPSize();
|
sz = GetFPSize();
|
p = inptr;
|
p = inptr;
|
Rt = getFPRegister();
|
Rt = getFPRegister();
|
if (Rt < 0) {
|
if (Rt < 0) {
|
printf("Expecting a target register (1:%d).\r\n", lineno);
|
printf("Expecting a target register (1:%d).\r\n", lineno);
|
printf("Line:%.60s\r\n",p);
|
printf("Line:%.60s\r\n",p);
|
ScanToEOL();
|
ScanToEOL();
|
inptr-=2;
|
inptr-=2;
|
return;
|
return;
|
}
|
}
|
expect(',');
|
expect(',');
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
mem_operand(&disp, &Ra, &Rb, &Sc);
|
if (Ra > 0 && Rb > 0) {
|
if (Ra > 0 && Rb > 0) {
|
emit_insn(
|
emit_insn(
|
((opcode6+sz) << 26) |
|
((opcode6+sz) << 26) |
|
(Sc << 23) |
|
(Sc << 23) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Rb << 13) |
|
(Rb << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x16,!expand_flag,4);
|
0x16,!expand_flag,4);
|
return;
|
return;
|
}
|
}
|
if (Ra < 0) Ra = 0;
|
if (Ra < 0) Ra = 0;
|
val = disp;
|
val = disp;
|
if (!IsNBit(val, 30)) {
|
if (!IsNBit(val, 30)) {
|
LoadConstant(val, 23);
|
LoadConstant(val, 23);
|
// Change to indexed addressing
|
// Change to indexed addressing
|
emit_insn(
|
emit_insn(
|
((opcode6+sz) << 26LL) |
|
((opcode6+sz) << 26LL) |
|
(0 << 23) | // Sc = 0
|
(0 << 23) | // Sc = 0
|
(Rt << 18) |
|
(Rt << 18) |
|
(23 << 13) |
|
(23 << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02, !expand_flag, 4);
|
0x02, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
switch (sz) {
|
switch (sz) {
|
case 0: val &= 0xfffffffffffffffeLL; val |= 1; break;
|
case 0: val &= 0xfffffffffffffffeLL; val |= 1; break;
|
case 1: val &= 0xfffffffffffffffcLL; val |= 2; break;
|
case 1: val &= 0xfffffffffffffffcLL; val |= 2; break;
|
case 2: val &= 0xfffffffffffffff8LL; val |= 4; break;
|
case 2: val &= 0xfffffffffffffff8LL; val |= 4; break;
|
case 4: val &= 0xfffffffffffffff0LL; val |= 8; break;
|
case 4: val &= 0xfffffffffffffff0LL; val |= 8; break;
|
}
|
}
|
if (!IsNBit(val, 14)) {
|
if (!IsNBit(val, 14)) {
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
(1 << 6) |
|
(1 << 6) |
|
opcode6, !expand_flag, 6);
|
opcode6, !expand_flag, 6);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(val << 18LL) |
|
(val << 18LL) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
opcode6, !expand_flag, 4);
|
opcode6, !expand_flag, 4);
|
ScanToEOL();
|
ScanToEOL();
|
|
|
}
|
}
|
|
|
static void process_ld()
|
static void process_ld()
|
{
|
{
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
expect(',');
|
expect(',');
|
// NextToken();
|
// NextToken();
|
if (token == '#') {
|
if (token == '#') {
|
inptr = p;
|
inptr = p;
|
process_ldi();
|
process_ldi();
|
return;
|
return;
|
}
|
}
|
// Else: do a word load
|
// Else: do a word load
|
inptr = p;
|
inptr = p;
|
process_load(0x20,4);
|
process_load(0x20,4);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_ltcb(int oc)
|
static void process_ltcb(int oc)
|
{
|
{
|
int Rn;
|
int Rn;
|
|
|
Rn = getRegisterX();
|
Rn = getRegisterX();
|
emit_insn(
|
emit_insn(
|
(oc << 11) |
|
(oc << 11) |
|
(Rn << 6) |
|
(Rn << 6) |
|
0x19,0,1
|
0x19,0,1
|
);
|
);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// mov r1,r2 -> translated to or Rt,Ra,#0
|
// mov r1,r2 -> translated to or Rt,Ra,#0
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_mov(int64_t oc, int64_t fn)
|
static void process_mov(int64_t oc, int64_t fn)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int vec = 0;
|
int vec = 0;
|
int fp = 0;
|
int fp = 0;
|
int d3;
|
int d3;
|
int rgs = 8;
|
int rgs = 8;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p == '.')
|
if (*p == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
d3 = 7; // current to current
|
d3 = 7; // current to current
|
p = inptr;
|
p = inptr;
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
if (Rt==-1) {
|
if (Rt==-1) {
|
inptr = p;
|
inptr = p;
|
Rt = getFPRegister();
|
Rt = getFPRegister();
|
if (Rt == -1) {
|
if (Rt == -1) {
|
d3 = 4;
|
d3 = 4;
|
inptr = p;
|
inptr = p;
|
vec = 1;
|
vec = 1;
|
Rt = getVecRegister();
|
Rt = getVecRegister();
|
}
|
}
|
else {
|
else {
|
d3 = 4;
|
d3 = 4;
|
fp = 1;
|
fp = 1;
|
}
|
}
|
}
|
}
|
Rt &= 31;
|
Rt &= 31;
|
if (inptr[-1]==':') {
|
if (inptr[-1]==':') {
|
if (*inptr=='x' || *inptr=='X') {
|
if (*inptr=='x' || *inptr=='X') {
|
d3 = 2;
|
d3 = 2;
|
inptr++;
|
inptr++;
|
NextToken();
|
NextToken();
|
}
|
}
|
else {
|
else {
|
rgs = (int)expr();
|
rgs = (int)expr();
|
d3 = 0;
|
d3 = 0;
|
}
|
}
|
}
|
}
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra==-1) {
|
if (Ra==-1) {
|
inptr = p;
|
inptr = p;
|
Ra = getFPRegister();
|
Ra = getFPRegister();
|
if (Ra == -1) {
|
if (Ra == -1) {
|
inptr = p;
|
inptr = p;
|
Ra = getVecRegister();
|
Ra = getVecRegister();
|
vec |= 2;
|
vec |= 2;
|
}
|
}
|
else {
|
else {
|
if (fp == 1)
|
if (fp == 1)
|
d3 = 6;
|
d3 = 6;
|
else
|
else
|
d3 = 5;
|
d3 = 5;
|
fp |= 2;
|
fp |= 2;
|
}
|
}
|
}
|
}
|
Ra &= 31;
|
Ra &= 31;
|
if (inptr[-1]==':') {
|
if (inptr[-1]==':') {
|
if (*inptr=='x' || *inptr=='X') {
|
if (*inptr=='x' || *inptr=='X') {
|
inptr++;
|
inptr++;
|
d3 = 3;
|
d3 = 3;
|
NextToken();
|
NextToken();
|
}
|
}
|
else {
|
else {
|
rgs = (int)expr();
|
rgs = (int)expr();
|
d3 = 1;
|
d3 = 1;
|
}
|
}
|
}
|
}
|
if (vec==1) {
|
if (vec==1) {
|
emit_insn(
|
emit_insn(
|
(0x33LL << 34LL) |
|
(0x33LL << 34LL) |
|
(0x00LL << 28LL) |
|
(0x00LL << 28LL) |
|
(Rt << 12) |
|
(Rt << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x01,!expand_flag,5
|
0x01,!expand_flag,5
|
);
|
);
|
return;
|
return;
|
}
|
}
|
else if (vec==2) {
|
else if (vec==2) {
|
emit_insn(
|
emit_insn(
|
(0x33LL << 34LL) |
|
(0x33LL << 34LL) |
|
(0x01LL << 28LL) |
|
(0x01LL << 28LL) |
|
(Rt << 12) |
|
(Rt << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x01,!expand_flag,5
|
0x01,!expand_flag,5
|
);
|
);
|
return;
|
return;
|
}
|
}
|
else if (vec==3)
|
else if (vec==3)
|
printf("Unsupported mov operation. %d\n", lineno);
|
printf("Unsupported mov operation. %d\n", lineno);
|
if (rgs < 0 || rgs > 63)
|
if (rgs < 0 || rgs > 63)
|
printf("Illegal register set spec: %d\n", lineno);
|
printf("Illegal register set spec: %d\n", lineno);
|
rgs &= 0x31;
|
rgs &= 0x31;
|
if (d3 == 7) {
|
if (d3 == 7) {
|
emit_insn(
|
emit_insn(
|
(0 << 12) |
|
(0 << 12) |
|
(3 << 6) |
|
(3 << 6) |
|
((Rt >> 1) << 8) |
|
((Rt >> 1) << 8) |
|
((Rt & 1) << 5) |
|
((Rt & 1) << 5) |
|
(Ra),
|
(Ra),
|
0,2);
|
0,2);
|
prevToken();
|
prevToken();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(fn << 26LL) | // fn should be even
|
(fn << 26LL) | // fn should be even
|
(((rgs >> 5) & 1) << 26) |
|
(((rgs >> 5) & 1) << 26) |
|
(d3 << 23LL) |
|
(d3 << 23LL) |
|
(rgs << 18) |
|
(rgs << 18) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
oc,!expand_flag,4
|
oc,!expand_flag,4
|
);
|
);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
static void process_vmov(int opcode, int func)
|
static void process_vmov(int opcode, int func)
|
{
|
{
|
int Vt, Va;
|
int Vt, Va;
|
int Rt, Ra;
|
int Rt, Ra;
|
|
|
Vt = getVecRegister();
|
Vt = getVecRegister();
|
if (Vt < 0x20) {
|
if (Vt < 0x20) {
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
if (Rt < 0) {
|
if (Rt < 0) {
|
printf("Illegal register in vmov (%d)\n", lineno);
|
printf("Illegal register in vmov (%d)\n", lineno);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
Va = getVecRegister();
|
Va = getVecRegister();
|
if (Va < 0x20) {
|
if (Va < 0x20) {
|
printf("Illegal register in vmov (%d)\n", lineno);
|
printf("Illegal register in vmov (%d)\n", lineno);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(func << 26) |
|
(func << 26) |
|
(1 << 21) |
|
(1 << 21) |
|
((Rt & 0x1f) << 11) |
|
((Rt & 0x1f) << 11) |
|
((Va & 0x1F) << 6) |
|
((Va & 0x1F) << 6) |
|
opcode,!expand_flag,4
|
opcode,!expand_flag,4
|
);
|
);
|
return;
|
return;
|
}
|
}
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
if (Ra < 0) {
|
if (Ra < 0) {
|
printf("Illegal register in vmov (%d)\n", lineno);
|
printf("Illegal register in vmov (%d)\n", lineno);
|
ScanToEOL();
|
ScanToEOL();
|
return;
|
return;
|
}
|
}
|
emit_insn(
|
emit_insn(
|
(func << 26) |
|
(func << 26) |
|
((Vt & 0x1f) << 11) |
|
((Vt & 0x1f) << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
opcode,!expand_flag,4
|
opcode,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// shr r1,r2,#5
|
// shr r1,r2,#5
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_shifti(int64_t op4)
|
static void process_shifti(int64_t op4)
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
int sz = 3;
|
int sz = 3;
|
int64_t func6 = 0x0F;
|
int64_t func6 = 0x0F;
|
int64_t val;
|
int64_t val;
|
char *p = inptr;
|
char *p = inptr;
|
|
|
if (p[0]=='.')
|
if (p[0]=='.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
val = expr();
|
val = expr();
|
val &= 63;
|
val &= 63;
|
if (val < 32 && op4 == 0 && Rt==Ra) {
|
if (val < 32 && op4 == 0 && Rt==Ra) {
|
emit_insn(
|
emit_insn(
|
(3 << 12) |
|
(3 << 12) |
|
(((val >> 1) & 0x0f) << 8) |
|
(((val >> 1) & 0x0f) << 8) |
|
(2 << 6) |
|
(2 << 6) |
|
((val & 1) << 5) |
|
((val & 1) << 5) |
|
Rt,0,2
|
Rt,0,2
|
);
|
);
|
return;
|
return;
|
}
|
}
|
if (val > 31)
|
if (val > 31)
|
func6 += 0x10;
|
func6 += 0x10;
|
emit_insn(
|
emit_insn(
|
(func6 << 26LL) |
|
(func6 << 26LL) |
|
(op4 << 23LL) |
|
(op4 << 23LL) |
|
((val & 0x1f) << 18) |
|
((val & 0x1f) << 18) |
|
(Rt << 13) |
|
(Rt << 13) |
|
(Ra << 8) |
|
(Ra << 8) |
|
0x02,!expand_flag,4);
|
0x02,!expand_flag,4);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// SEI R1
|
// SEI R1
|
// SEI #5
|
// SEI #5
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_sei()
|
static void process_sei()
|
{
|
{
|
int64_t val = 7;
|
int64_t val = 7;
|
int Ra = -1;
|
int Ra = -1;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
NextToken();
|
NextToken();
|
if (token=='#')
|
if (token=='#')
|
val = expr();
|
val = expr();
|
else {
|
else {
|
inptr = p;
|
inptr = p;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
}
|
}
|
if (Ra==-1) {
|
if (Ra==-1) {
|
emit_insn(
|
emit_insn(
|
0xC0000002LL |
|
0xC0000002LL |
|
((val & 7) << 18) |
|
((val & 7) << 18) |
|
(0 << 8),
|
(0 << 8),
|
!expand_flag,4);
|
!expand_flag,4);
|
}
|
}
|
else {
|
else {
|
emit_insn(
|
emit_insn(
|
0xC0000002LL |
|
0xC0000002LL |
|
(0 << 18) |
|
(0 << 18) |
|
(Ra << 8),
|
(Ra << 8),
|
!expand_flag,4);
|
!expand_flag,4);
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// REX r0,6,6,1
|
// REX r0,6,6,1
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_rex()
|
static void process_rex()
|
{
|
{
|
int64_t val = 7;
|
int64_t val = 7;
|
int Ra = -1;
|
int Ra = -1;
|
int tgtol;
|
int tgtol;
|
int pl;
|
int pl;
|
int im;
|
int im;
|
char *p;
|
char *p;
|
|
|
p = inptr;
|
p = inptr;
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
tgtol = (int)expr() & 7;
|
tgtol = (int)expr() & 7;
|
if (tgtol==0)
|
if (tgtol==0)
|
printf("REX: Illegal redirect to user level %d.\n", lineno);
|
printf("REX: Illegal redirect to user level %d.\n", lineno);
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
pl = (int)expr() & 7;
|
pl = (int)expr() & 7;
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
im = (int)expr() & 7;
|
im = (int)expr() & 7;
|
emit_insn(
|
emit_insn(
|
(im << 24) |
|
(im << 24) |
|
(pl << 16) |
|
(pl << 16) |
|
(tgtol << 11) |
|
(tgtol << 11) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x0D,!expand_flag,4
|
0x0D,!expand_flag,4
|
);
|
);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// shl r1,r2,r3
|
// shl r1,r2,r3
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_shift(int op4)
|
static void process_shift(int op4)
|
{
|
{
|
int Ra, Rb;
|
int Ra, Rb;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
int func6 = 0x2f;
|
int func6 = 0x2f;
|
|
|
p = inptr;
|
p = inptr;
|
if (p[0]=='.')
|
if (p[0]=='.')
|
getSz(&sz);
|
getSz(&sz);
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
inptr = p;
|
inptr = p;
|
process_shifti(op4);
|
process_shifti(op4);
|
}
|
}
|
else {
|
else {
|
prevToken();
|
prevToken();
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
emit_insn((func6 << 26) | (op4 << 23) | (Rt << 18)| (Rb << 12) | (Ra << 8) | 0x02,!expand_flag,4);
|
emit_insn((func6 << 26) | (op4 << 23) | (Rt << 18)| (Rb << 12) | (Ra << 8) | 0x02,!expand_flag,4);
|
}
|
}
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// gran r1
|
// gran r1
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_gran(int oc)
|
static void process_gran(int oc)
|
{
|
{
|
int Rt;
|
int Rt;
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
// emitAlignedCode(0x01);
|
// emitAlignedCode(0x01);
|
emitCode(0x00);
|
emitCode(0x00);
|
emitCode(Rt);
|
emitCode(Rt);
|
emitCode(0x00);
|
emitCode(0x00);
|
emitCode(oc);
|
emitCode(oc);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_mffp(int oc)
|
static void process_mffp(int oc)
|
{
|
{
|
int fpr;
|
int fpr;
|
int Rt;
|
int Rt;
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
fpr = getFPRegister();
|
fpr = getFPRegister();
|
//emitAlignedCode(0x01);
|
//emitAlignedCode(0x01);
|
emitCode(fpr);
|
emitCode(fpr);
|
emitCode(Rt);
|
emitCode(Rt);
|
emitCode(0x00);
|
emitCode(0x00);
|
emitCode(oc);
|
emitCode(oc);
|
if (fpr >= 0)
|
if (fpr >= 0)
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_fprdstat(int oc)
|
static void process_fprdstat(int oc)
|
{
|
{
|
int Rt;
|
int Rt;
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
//emitAlignedCode(0x01);
|
//emitAlignedCode(0x01);
|
emitCode(0x00);
|
emitCode(0x00);
|
emitCode(Rt);
|
emitCode(Rt);
|
emitCode(0x00);
|
emitCode(0x00);
|
emitCode(oc);
|
emitCode(oc);
|
}
|
}
|
|
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// Four cases, two with extendable immediate constants
|
// Four cases, two with extendable immediate constants
|
//
|
//
|
// csrrw r2,#21,r3
|
// csrrw r2,#21,r3
|
// csrrw r4,#34,#1234
|
// csrrw r4,#34,#1234
|
// csrrw r5,r4,#1234
|
// csrrw r5,r4,#1234
|
// csrrw r6,r4,r5
|
// csrrw r6,r4,r5
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void process_csrrw(int64_t op)
|
static void process_csrrw(int64_t op)
|
{
|
{
|
int Rd;
|
int Rd;
|
int Rs;
|
int Rs;
|
int Rc;
|
int Rc;
|
int64_t val,val2;
|
int64_t val,val2;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (p[0] == '.')
|
if (p[0] == '.')
|
getSz(&sz);
|
getSz(&sz);
|
Rd = getRegisterX();
|
Rd = getRegisterX();
|
need(',');
|
need(',');
|
p = inptr;
|
p = inptr;
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
val = expr();
|
val = expr();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
printf("Illegal CSR instruction.\r\n");
|
printf("Illegal CSR instruction.\r\n");
|
return;
|
return;
|
val2 = expr();
|
val2 = expr();
|
if (val2 < -15LL || val2 > 15LL) {
|
if (val2 < -15LL || val2 > 15LL) {
|
emit_insn((val << 18) | (op << 16) | (0x10 << 6) | (Rd << 11) | 0x05,0,2);
|
emit_insn((val << 18) | (op << 16) | (0x10 << 6) | (Rd << 11) | 0x05,0,2);
|
emit_insn(val2,0,2);
|
emit_insn(val2,0,2);
|
return;
|
return;
|
}
|
}
|
emit_insn((val << 18) | (op << 16) | ((val2 & 0x1f) << 6) | (Rd << 11) | 0x05,!expand_flag,2);
|
emit_insn((val << 18) | (op << 16) | ((val2 & 0x1f) << 6) | (Rd << 11) | 0x05,!expand_flag,2);
|
return;
|
return;
|
}
|
}
|
prevToken();
|
prevToken();
|
Rs = getRegisterX();
|
Rs = getRegisterX();
|
emit_insn(((val & 0x3FF) << 18) | (op << 30LL) | (Rs << 8) | (Rd << 13) | 0x05,!expand_flag,4);
|
emit_insn(((val & 0x3FF) << 18) | (op << 30LL) | (Rs << 8) | (Rd << 13) | 0x05,!expand_flag,4);
|
prevToken();
|
prevToken();
|
return;
|
return;
|
}
|
}
|
printf("Illegal CSR instruction.\r\n");
|
printf("Illegal CSR instruction.\r\n");
|
return;
|
return;
|
inptr = p;
|
inptr = p;
|
Rc = getRegisterX();
|
Rc = getRegisterX();
|
need(',');
|
need(',');
|
NextToken();
|
NextToken();
|
if (token=='#') {
|
if (token=='#') {
|
val2 = expr();
|
val2 = expr();
|
if (val2 < -15LL || val2 > 15LL) {
|
if (val2 < -15LL || val2 > 15LL) {
|
emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | (0x10 << 6) | (Rc << 11) | 0x0C,0,2);
|
emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | (0x10 << 6) | (Rc << 11) | 0x0C,0,2);
|
emit_insn(val2,0,2);
|
emit_insn(val2,0,2);
|
return;
|
return;
|
}
|
}
|
emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | ((val2 & 0x1f) << 6) | (Rc << 11) | 0x0C,!expand_flag,2);
|
emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | ((val2 & 0x1f) << 6) | (Rc << 11) | 0x0C,!expand_flag,2);
|
return;
|
return;
|
}
|
}
|
prevToken();
|
prevToken();
|
Rs = getRegisterX();
|
Rs = getRegisterX();
|
emit_insn((0x3F << 26) | (op << 21) | (Rd << 16) | (Rc << 11) | (Rs << 6) | 0x0C,!expand_flag,2);
|
emit_insn((0x3F << 26) | (op << 21) | (Rd << 16) | (Rc << 11) | (Rs << 6) | 0x0C,!expand_flag,2);
|
prevToken();
|
prevToken();
|
return;
|
return;
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// com r3,r3
|
// com r3,r3
|
// - alternate mnemonic for xor Rn,Rn,#-1
|
// - alternate mnemonic for xor Rn,Rn,#-1
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_com()
|
static void process_com()
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (p[0] == '.')
|
if (p[0] == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
emit_insn(
|
emit_insn(
|
(0xFFFFFLL << 20) |
|
(0xFFFFFLL << 20) |
|
(sz << 18) |
|
(sz << 18) |
|
(Rt << 12) |
|
(Rt << 12) |
|
(Ra << 6) |
|
(Ra << 6) |
|
0x0A,!expand_flag,5
|
0x0A,!expand_flag,5
|
);
|
);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// neg r3,r3
|
// neg r3,r3
|
// - alternate mnemonic for sub Rn,R0,Rn
|
// - alternate mnemonic for sub Rn,R0,Rn
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_neg()
|
static void process_neg()
|
{
|
{
|
int Ra;
|
int Ra;
|
int Rt;
|
int Rt;
|
char *p;
|
char *p;
|
int sz = 3;
|
int sz = 3;
|
|
|
p = inptr;
|
p = inptr;
|
if (p[0] == '.')
|
if (p[0] == '.')
|
getSz(&sz);
|
getSz(&sz);
|
|
|
Rt = getRegisterX();
|
Rt = getRegisterX();
|
need(',');
|
need(',');
|
Ra = getRegisterX();
|
Ra = getRegisterX();
|
emit_insn(
|
emit_insn(
|
(0x05LL << 34LL) |
|
(0x05LL << 34LL) |
|
(sz << 24) |
|
(sz << 24) |
|
(Rt << 18) |
|
(Rt << 18) |
|
(Ra << 12) |
|
(Ra << 12) |
|
(0 << 6) |
|
(0 << 6) |
|
0x02,!expand_flag,5
|
0x02,!expand_flag,5
|
);
|
);
|
prevToken();
|
prevToken();
|
}
|
}
|
|
|
static void process_sync(int oc)
|
static void process_sync(int oc)
|
{
|
{
|
// emit_insn(oc,!expand_flag);
|
// emit_insn(oc,!expand_flag);
|
}
|
}
|
|
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_vrrop(int funct6)
|
static void process_vrrop(int funct6)
|
{
|
{
|
int Va,Vb,Vt,Vm;
|
int Va,Vb,Vt,Vm;
|
char *p;
|
char *p;
|
int sz = 0x43;
|
int sz = 0x43;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p=='.')
|
if (*p=='.')
|
getSz(&sz);
|
getSz(&sz);
|
if (sz==0x43)
|
if (sz==0x43)
|
sz = 0;
|
sz = 0;
|
else if (sz==0x83)
|
else if (sz==0x83)
|
sz = 1;
|
sz = 1;
|
Vt = getVecRegister();
|
Vt = getVecRegister();
|
need(',');
|
need(',');
|
Va = getVecRegister();
|
Va = getVecRegister();
|
need(',');
|
need(',');
|
Vb = getVecRegister();
|
Vb = getVecRegister();
|
need(',');
|
need(',');
|
Vm = getVecRegister();
|
Vm = getVecRegister();
|
if (Vm < 0x20 || Vm > 0x23)
|
if (Vm < 0x20 || Vm > 0x23)
|
printf("Illegal vector mask register: %d\r\n", lineno);
|
printf("Illegal vector mask register: %d\r\n", lineno);
|
Vm &= 0x7;
|
Vm &= 0x7;
|
//prevToken();
|
//prevToken();
|
emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Vb<<11)|(Va<<6)|0x01,!expand_flag,4);
|
emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Vb<<11)|(Va<<6)|0x01,!expand_flag,4);
|
}
|
}
|
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
static void process_vsrrop(int funct6)
|
static void process_vsrrop(int funct6)
|
{
|
{
|
int Va,Rb,Vt,Vm;
|
int Va,Rb,Vt,Vm;
|
char *p;
|
char *p;
|
int sz = 0x43;
|
int sz = 0x43;
|
|
|
p = inptr;
|
p = inptr;
|
if (*p=='.')
|
if (*p=='.')
|
getSz(&sz);
|
getSz(&sz);
|
if (sz==0x43)
|
if (sz==0x43)
|
sz = 0;
|
sz = 0;
|
else if (sz==0x83)
|
else if (sz==0x83)
|
sz = 1;
|
sz = 1;
|
Vt = getVecRegister();
|
Vt = getVecRegister();
|
need(',');
|
need(',');
|
Va = getVecRegister();
|
Va = getVecRegister();
|
need(',');
|
need(',');
|
Rb = getRegisterX();
|
Rb = getRegisterX();
|
need(',');
|
need(',');
|
Vm = getVecRegister();
|
Vm = getVecRegister();
|
if (Vm < 0x20 || Vm > 0x23)
|
if (Vm < 0x20 || Vm > 0x23)
|
printf("Illegal vector mask register: %d\r\n", lineno);
|
printf("Illegal vector mask register: %d\r\n", lineno);
|
Vm &= 0x3;
|
Vm &= 0x3;
|
//prevToken();
|
//prevToken();
|
emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Rb<<11)|(Va<<6)|0x01,!expand_flag,4);
|
emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Rb<<11)|(Va<<6)|0x01,!expand_flag,4);
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
static void ProcessEOL(int opt)
|
static void ProcessEOL(int opt)
|
{
|
{
|
int64_t nn,mm,cai,caia;
|
int64_t nn,mm,cai,caia;
|
int first;
|
int first;
|
int cc,jj;
|
int cc,jj;
|
|
|
//printf("Line: %d\r", lineno);
|
//printf("Line: %d\r", lineno);
|
expand_flag = 0;
|
expand_flag = 0;
|
compress_flag = 0;
|
compress_flag = 0;
|
segprefix = -1;
|
segprefix = -1;
|
if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
|
if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
|
nn = binstart;
|
nn = binstart;
|
cc = 2;
|
cc = 2;
|
if (segment==codeseg) {
|
if (segment==codeseg) {
|
cc = 4;
|
cc = 4;
|
/*
|
/*
|
if (sections[segment].bytes[binstart]==0x61) {
|
if (sections[segment].bytes[binstart]==0x61) {
|
fprintf(ofp, "%06LLX ", ca);
|
fprintf(ofp, "%06LLX ", ca);
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
}
|
}
|
fprintf(ofp, " ; imm\n");
|
fprintf(ofp, " ; imm\n");
|
if (((ca+5) & 15)==15) {
|
if (((ca+5) & 15)==15) {
|
ca+=6;
|
ca+=6;
|
binstart+=6;
|
binstart+=6;
|
nn++;
|
nn++;
|
}
|
}
|
else {
|
else {
|
ca += 5;
|
ca += 5;
|
binstart += 5;
|
binstart += 5;
|
}
|
}
|
}
|
}
|
*/
|
*/
|
/*
|
/*
|
if (sections[segment].bytes[binstart]==0xfd) {
|
if (sections[segment].bytes[binstart]==0xfd) {
|
fprintf(ofp, "%06LLX ", ca);
|
fprintf(ofp, "%06LLX ", ca);
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
}
|
}
|
fprintf(ofp, " ; imm\n");
|
fprintf(ofp, " ; imm\n");
|
if (((ca+5) & 15)==15) {
|
if (((ca+5) & 15)==15) {
|
ca+=6;
|
ca+=6;
|
binstart+=6;
|
binstart+=6;
|
nn++;
|
nn++;
|
}
|
}
|
else {
|
else {
|
ca += 5;
|
ca += 5;
|
binstart += 5;
|
binstart += 5;
|
}
|
}
|
}
|
}
|
if (sections[segment].bytes[binstart]==0xfe) {
|
if (sections[segment].bytes[binstart]==0xfe) {
|
fprintf(ofp, "%06LLX ", ca);
|
fprintf(ofp, "%06LLX ", ca);
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
|
}
|
}
|
fprintf(ofp, " ; imm\n");
|
fprintf(ofp, " ; imm\n");
|
if (((ca+5) & 15)==15) {
|
if (((ca+5) & 15)==15) {
|
ca+=6;
|
ca+=6;
|
nn++;
|
nn++;
|
}
|
}
|
else {
|
else {
|
ca += 5;
|
ca += 5;
|
}
|
}
|
}
|
}
|
*/
|
*/
|
}
|
}
|
|
|
first = 1;
|
first = 1;
|
while (nn < sections[segment].index) {
|
while (nn < sections[segment].index) {
|
fprintf(ofp, "%06I64X ", ca);
|
fprintf(ofp, "%06I64X ", ca);
|
caia = 0;
|
caia = 0;
|
for (mm = nn; nn < mm + cc && nn < sections[segment].index; ) {
|
for (mm = nn; nn < mm + cc && nn < sections[segment].index; ) {
|
cai = sections[segment].index - nn;
|
cai = sections[segment].index - nn;
|
// Output for instructions with multiple words
|
// Output for instructions with multiple words
|
if ((cai % 4) == 0 && cai < 20 && segment==codeseg)
|
if ((cai % 4) == 0 && cai < 20 && segment==codeseg)
|
cai = 4;
|
cai = 4;
|
// Otherwise a big stream of information was output, likely data
|
// Otherwise a big stream of information was output, likely data
|
if (cai > 8) cai = 8;
|
if (cai > 8) cai = 8;
|
// for (jj = (int)cai-1; jj >= 0; jj--)
|
// for (jj = (int)cai-1; jj >= 0; jj--)
|
// fprintf(ofp, "%02X", sections[segment].bytes[nn+jj]);
|
// fprintf(ofp, "%02X", sections[segment].bytes[nn+jj]);
|
for (jj = 0; jj < (int) cai; jj++)
|
for (jj = 0; jj < (int) cai; jj++)
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn + jj]);
|
fprintf(ofp, "%02X ", sections[segment].bytes[nn + jj]);
|
fprintf(ofp, " ");
|
fprintf(ofp, " ");
|
nn += cai;
|
nn += cai;
|
caia += cai;
|
caia += cai;
|
}
|
}
|
for (jj = 8 - (int)caia; jj >= 0; jj--)
|
for (jj = 8 - (int)caia; jj >= 0; jj--)
|
fprintf(ofp, " ");
|
fprintf(ofp, " ");
|
// for (; nn < mm + caia; nn++)
|
// for (; nn < mm + caia; nn++)
|
// fprintf(ofp, " ");
|
// fprintf(ofp, " ");
|
if (first & opt) {
|
if (first & opt) {
|
fprintf(ofp, "\t%.*s\n", inptr - stptr - 1, stptr);
|
fprintf(ofp, "\t%.*s\n", inptr - stptr - 1, stptr);
|
first = 0;
|
first = 0;
|
}
|
}
|
else
|
else
|
fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
|
fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
|
ca += caia;
|
ca += caia;
|
}
|
}
|
// empty (codeless) line
|
// empty (codeless) line
|
if (binstart==sections[segment].index) {
|
if (binstart==sections[segment].index) {
|
fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
|
fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
|
}
|
}
|
} // bGen
|
} // bGen
|
if (opt) {
|
if (opt) {
|
stptr = inptr;
|
stptr = inptr;
|
lineno++;
|
lineno++;
|
}
|
}
|
binstart = sections[segment].index;
|
binstart = sections[segment].index;
|
ca = sections[segment].address;
|
ca = sections[segment].address;
|
}
|
}
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
void FT64_processMaster()
|
void FT64_processMaster()
|
{
|
{
|
int nn;
|
int nn;
|
int64_t bs1, bs2;
|
int64_t bs1, bs2;
|
|
|
lineno = 1;
|
lineno = 1;
|
binndx = 0;
|
binndx = 0;
|
binstart = 0;
|
binstart = 0;
|
bs1 = 0;
|
bs1 = 0;
|
bs2 = 0;
|
bs2 = 0;
|
inptr = &masterFile[0];
|
inptr = &masterFile[0];
|
stptr = inptr;
|
stptr = inptr;
|
code_address = 0;
|
code_address = 0;
|
bss_address = 0;
|
bss_address = 0;
|
start_address = 0;
|
start_address = 0;
|
first_org = 1;
|
first_org = 1;
|
first_rodata = 1;
|
first_rodata = 1;
|
first_data = 1;
|
first_data = 1;
|
first_bss = 1;
|
first_bss = 1;
|
expandedBlock = 0;
|
expandedBlock = 0;
|
if (pass<3) {
|
if (pass==3) {
|
htblmax = 0;
|
htblmax = 0;
|
for (nn = 0; nn < 100000; nn++) {
|
for (nn = 0; nn < 100000; nn++) {
|
hTable[nn].count = 0;
|
hTable[nn].count = 0;
|
hTable[nn].opcode = 0;
|
hTable[nn].opcode = 0;
|
}
|
}
|
}
|
}
|
for (nn = 0; nn < 12; nn++) {
|
for (nn = 0; nn < 12; nn++) {
|
sections[nn].index = 0;
|
sections[nn].index = 0;
|
if (nn == 0)
|
if (nn == 0)
|
sections[nn].address = 0;
|
sections[nn].address = 0;
|
else
|
else
|
sections[nn].address = 0;
|
sections[nn].address = 0;
|
sections[nn].start = 0;
|
sections[nn].start = 0;
|
sections[nn].end = 0;
|
sections[nn].end = 0;
|
}
|
}
|
ca = code_address;
|
ca = code_address;
|
segment = codeseg;
|
segment = codeseg;
|
memset(current_label,0,sizeof(current_label));
|
memset(current_label,0,sizeof(current_label));
|
NextToken();
|
NextToken();
|
while (token != tk_eof) {
|
while (token != tk_eof) {
|
// printf("\t%.*s\n", inptr-stptr-1, stptr);
|
// printf("\t%.*s\n", inptr-stptr-1, stptr);
|
// printf("token=%d\r", token);
|
// printf("token=%d\r", token);
|
if (expandedBlock)
|
if (expandedBlock)
|
expand_flag = 1;
|
expand_flag = 1;
|
switch(token) {
|
switch(token) {
|
case tk_eol: ProcessEOL(1); break;
|
case tk_eol: ProcessEOL(1); break;
|
// case tk_add: process_add(); break;
|
// case tk_add: process_add(); break;
|
// case tk_abs: process_rop(0x04); break;
|
// case tk_abs: process_rop(0x04); break;
|
case tk_abs: process_rop(0x01); break;
|
case tk_abs: process_rop(0x01); break;
|
case tk_add: process_rrop(0x04,0x04); break;
|
case tk_add: process_rrop(0x04,0x04); break;
|
case tk_addi: process_riop(0x04); break;
|
case tk_addi: process_riop(0x04); break;
|
case tk_align: process_align(); continue; break;
|
case tk_align: process_align(); continue; break;
|
case tk_and: process_rrop(0x08,0x08); break;
|
case tk_and: process_rrop(0x08,0x08); break;
|
case tk_andi: process_riop(0x08); break;
|
case tk_andi: process_riop(0x08); break;
|
case tk_asl: process_shift(0x2); break;
|
case tk_asl: process_shift(0x2); break;
|
case tk_asr: process_shift(0x3); break;
|
case tk_asr: process_shift(0x3); break;
|
case tk_bbc: process_beqi(0x26,1); break;
|
case tk_bbc: process_beqi(0x26,1); break;
|
case tk_bbs: process_beqi(0x26,0); break;
|
case tk_bbs: process_beqi(0x26,0); break;
|
case tk_begin_expand: expandedBlock = 1; break;
|
case tk_begin_expand: expandedBlock = 1; break;
|
case tk_beq: process_bcc(0x30,0); break;
|
case tk_beq: process_bcc(0x30,0); break;
|
case tk_beqi: process_beqi(0x32,0); break;
|
case tk_beqi: process_beqi(0x32,0); break;
|
case tk_bfchg: process_bitfield(2); break;
|
case tk_bfchg: process_bitfield(2); break;
|
case tk_bfclr: process_bitfield(1); break;
|
case tk_bfclr: process_bitfield(1); break;
|
case tk_bfext: process_bitfield(5); break;
|
case tk_bfext: process_bitfield(5); break;
|
case tk_bfextu: process_bitfield(6); break;
|
case tk_bfextu: process_bitfield(6); break;
|
case tk_bfins: process_bitfield(3); break;
|
case tk_bfins: process_bitfield(3); break;
|
case tk_bfinsi: process_bitfield(4); break;
|
case tk_bfinsi: process_bitfield(4); break;
|
case tk_bfset: process_bitfield(0); break;
|
case tk_bfset: process_bitfield(0); break;
|
case tk_bge: process_bcc(0x30,3); break;
|
case tk_bge: process_bcc(0x30,3); break;
|
case tk_bgeu: process_bcc(0x30,5); break;
|
case tk_bgeu: process_bcc(0x30,5); break;
|
case tk_bgt: process_bcc(0x30,-2); break;
|
case tk_bgt: process_bcc(0x30,-2); break;
|
case tk_bgtu: process_bcc(0x30,-4); break;
|
case tk_bgtu: process_bcc(0x30,-4); break;
|
case tk_ble: process_bcc(0x30,-3); break;
|
case tk_ble: process_bcc(0x30,-3); break;
|
case tk_bleu: process_bcc(0x30,-5); break;
|
case tk_bleu: process_bcc(0x30,-5); break;
|
case tk_blt: process_bcc(0x30,2); break;
|
case tk_blt: process_bcc(0x30,2); break;
|
case tk_bltu: process_bcc(0x30,4); break;
|
case tk_bltu: process_bcc(0x30,4); break;
|
case tk_bne: process_bcc(0x30,1); break;
|
case tk_bne: process_bcc(0x30,1); break;
|
case tk_bra: process_bra(0x01); break;
|
case tk_bra: process_bra(0x01); break;
|
case tk_brk: process_brk(); break;
|
case tk_brk: process_brk(); break;
|
//case tk_bsr: process_bra(0x56); break;
|
//case tk_bsr: process_bra(0x56); break;
|
case tk_bss:
|
case tk_bss:
|
if (first_bss) {
|
if (first_bss) {
|
while(sections[segment].address & 4095)
|
while(sections[segment].address & 4095)
|
emitByte(0x00);
|
emitByte(0x00);
|
sections[3].address = sections[segment].address;
|
sections[3].address = sections[segment].address;
|
first_bss = 0;
|
first_bss = 0;
|
binstart = sections[3].index;
|
binstart = sections[3].index;
|
ca = sections[3].address;
|
ca = sections[3].address;
|
}
|
}
|
segment = bssseg;
|
segment = bssseg;
|
break;
|
break;
|
case tk_cache: process_cache(0x1E); break;
|
case tk_cache: process_cache(0x1E); break;
|
case tk_call: process_call(0x19); break;
|
case tk_call: process_call(0x19); break;
|
case tk_cli: emit_insn(0xC0000002,0,4); break;
|
case tk_cli: emit_insn(0xC0000002,!expand_flag,4); break;
|
case tk_chk: process_chk(0x34); break;
|
case tk_chk: process_chk(0x34); break;
|
case tk_cmovenz: process_cmove(0x29); break;
|
case tk_cmovenz: process_cmove(0x29); break;
|
//case tk_cmp: process_rrop(0x06); break;
|
//case tk_cmp: process_rrop(0x06); break;
|
//case tk_cmpi: process_riop(0x06); break;
|
//case tk_cmpi: process_riop(0x06); break;
|
//case tk_cmpu: process_rrop(0x07); break;
|
//case tk_cmpu: process_rrop(0x07); break;
|
//case tk_cmpui: process_riop(0x07); break;
|
//case tk_cmpui: process_riop(0x07); break;
|
case tk_code: process_code(); break;
|
case tk_code: process_code(); break;
|
case tk_com: process_com(); break;
|
case tk_com: process_com(); break;
|
case tk_csrrc: process_csrrw(0x3); break;
|
case tk_csrrc: process_csrrw(0x3); break;
|
case tk_csrrs: process_csrrw(0x2); break;
|
case tk_csrrs: process_csrrw(0x2); break;
|
case tk_csrrw: process_csrrw(0x1); break;
|
case tk_csrrw: process_csrrw(0x1); break;
|
case tk_csrrd: process_csrrw(0x0); break;
|
case tk_csrrd: process_csrrw(0x0); break;
|
case tk_data:
|
case tk_data:
|
if (first_data) {
|
if (first_data) {
|
while(sections[segment].address & 4095)
|
while(sections[segment].address & 4095)
|
emitByte(0x00);
|
emitByte(0x00);
|
sections[2].address = sections[segment].address; // set starting address
|
sections[2].address = sections[segment].address; // set starting address
|
first_data = 0;
|
first_data = 0;
|
binstart = sections[2].index;
|
binstart = sections[2].index;
|
ca = sections[2].address;
|
ca = sections[2].address;
|
}
|
}
|
process_data(dataseg);
|
process_data(dataseg);
|
break;
|
break;
|
case tk_db: process_db(); break;
|
case tk_db: process_db(); break;
|
case tk_dbnz: process_dbnz(0x26,3); break;
|
case tk_dbnz: process_dbnz(0x26,3); break;
|
case tk_dc: process_dc(); break;
|
case tk_dc: process_dc(); break;
|
case tk_dec: process_inc(0x25); break;
|
case tk_dec: process_inc(0x25); break;
|
case tk_dh: process_dh(); break;
|
case tk_dh: process_dh(); break;
|
case tk_dh_htbl: process_dh_htbl(); break;
|
case tk_dh_htbl: process_dh_htbl(); break;
|
case tk_div: process_rrop(0x3E,0x3E); break;
|
case tk_div: process_rrop(0x3E,0x3E); break;
|
//case tk_divsu: process_rrop(0x3D, -1); break;
|
//case tk_divsu: process_rrop(0x3D, -1); break;
|
case tk_divu: process_rrop(0x3C,0x3C); break;
|
case tk_divu: process_rrop(0x3C,0x3C); break;
|
case tk_dw: process_dw(); break;
|
case tk_dw: process_dw(); break;
|
case tk_end: goto j1;
|
case tk_end: goto j1;
|
case tk_end_expand: expandedBlock = 0; break;
|
case tk_end_expand: expandedBlock = 0; break;
|
case tk_endpublic: break;
|
case tk_endpublic: break;
|
case tk_eor: process_rrop(0x0A,0x0A); break;
|
case tk_eor: process_rrop(0x0A,0x0A); break;
|
case tk_eori: process_riop(0x0A); break;
|
case tk_eori: process_riop(0x0A); break;
|
case tk_extern: process_extern(); break;
|
case tk_extern: process_extern(); break;
|
case tk_file:
|
case tk_file:
|
NextToken();
|
NextToken();
|
if (token==tk_strconst)
|
if (token==tk_strconst)
|
mname = std::string(laststr);
|
mname = std::string(laststr);
|
//NextToken();
|
//NextToken();
|
//if (token == ',') {
|
//if (token == ',') {
|
// NextToken();
|
// NextToken();
|
// lineno = expr();
|
// lineno = expr();
|
//}
|
//}
|
break;
|
break;
|
case tk_ftoi: process_ftoi(0x12); break;
|
case tk_ftoi: process_ftoi(0x12); break;
|
case tk_fadd: process_fprrop(0x04); break;
|
case tk_fadd: process_fprrop(0x04); break;
|
case tk_fbeq: process_fbcc(0); break;
|
case tk_fbeq: process_fbcc(0); break;
|
case tk_fbge: process_fbcc(3); break;
|
case tk_fbge: process_fbcc(3); break;
|
case tk_fblt: process_fbcc(2); break;
|
case tk_fblt: process_fbcc(2); break;
|
case tk_fbne: process_fbcc(1); break;
|
case tk_fbne: process_fbcc(1); break;
|
case tk_fdiv: process_fprrop(0x09); break;
|
case tk_fdiv: process_fprrop(0x09); break;
|
case tk_fill: process_fill(); break;
|
case tk_fill: process_fill(); break;
|
case tk_fmov: process_fprop(0x10); break;
|
case tk_fmov: process_fprop(0x10); break;
|
case tk_fmul: process_fprrop(0x08); break;
|
case tk_fmul: process_fprrop(0x08); break;
|
case tk_fneg: process_fprop(0x14); break;
|
case tk_fneg: process_fprop(0x14); break;
|
case tk_fsub: process_fprrop(0x05); break;
|
case tk_fsub: process_fprrop(0x05); break;
|
case tk_hint: process_hint(); break;
|
case tk_hint: process_hint(); break;
|
case tk_ibne: process_ibne(0x26,2); break;
|
case tk_ibne: process_ibne(0x26,2); break;
|
case tk_inc: process_inc(0x1A); break;
|
case tk_inc: process_inc(0x1A); break;
|
case tk_if: pif1 = inptr-2; doif(); break;
|
case tk_if: pif1 = inptr-2; doif(); break;
|
case tk_itof: process_itof(0x15); break;
|
case tk_itof: process_itof(0x15); break;
|
case tk_iret: process_iret(0xC8000002); break;
|
case tk_iret: process_iret(0xC8000002); break;
|
case tk_isnull: process_rop(0x0C); break;
|
case tk_isnull: process_rop(0x0C); break;
|
case tk_isptr: process_rop(0x0D); break;
|
case tk_isptr: process_rop(0x0D); break;
|
case tk_jal: process_jal(0x18); break;
|
case tk_jal: process_jal(0x18); break;
|
case tk_jmp: process_call(0x28); break;
|
case tk_jmp: process_call(0x28); break;
|
case tk_lb: process_load(0x13,0); break;
|
case tk_lb: process_load(0x13,0); break;
|
case tk_lbu: process_load(0x23,0); break;
|
case tk_lbu: process_load(0x23,0); break;
|
case tk_lc: process_load(0x20,1); break;
|
case tk_lc: process_load(0x20,1); break;
|
case tk_lcu: process_load(0x20,-1); break;
|
case tk_lcu: process_load(0x20,-1); break;
|
case tk_ld: process_ld(); break;
|
case tk_ld: process_ld(); break;
|
case tk_ldi: process_ldi(); break;
|
case tk_ldi: process_ldi(); break;
|
case tk_lea: process_load(0x04,0); break;
|
case tk_lea: process_load(0x04,0); break;
|
case tk_lf: process_lsfloat(0x1b,0x00); break;
|
case tk_lf: process_lsfloat(0x1b,0x00); break;
|
case tk_lh: process_load(0x20,2); break;
|
case tk_lh: process_load(0x20,2); break;
|
case tk_lhu: process_load(0x20,-2); break;
|
case tk_lhu: process_load(0x20,-2); break;
|
//case tk_lui: process_lui(0x27); break;
|
//case tk_lui: process_lui(0x27); break;
|
case tk_lv: process_lv(0x36); break;
|
case tk_lv: process_lv(0x36); break;
|
case tk_lvb: ProcessLoadVolatile(0x3B,1); break;
|
case tk_lvb: ProcessLoadVolatile(0x3B,1); break;
|
case tk_lvbu: ProcessLoadVolatile(0x3B,-1); break;
|
case tk_lvbu: ProcessLoadVolatile(0x3B,-1); break;
|
case tk_lvc: ProcessLoadVolatile(0x3B,2); break;
|
case tk_lvc: ProcessLoadVolatile(0x3B,2); break;
|
case tk_lvcu: ProcessLoadVolatile(0x3B,-2); break;
|
case tk_lvcu: ProcessLoadVolatile(0x3B,-2); break;
|
case tk_lvh: ProcessLoadVolatile(0x3B,4); break;
|
case tk_lvh: ProcessLoadVolatile(0x3B,4); break;
|
case tk_lvhu: ProcessLoadVolatile(0x3B,-4); break;
|
case tk_lvhu: ProcessLoadVolatile(0x3B,-4); break;
|
case tk_lvw: ProcessLoadVolatile(0x3B,8); break;
|
case tk_lvw: ProcessLoadVolatile(0x3B,8); break;
|
case tk_lw: process_load(0x20,4); break;
|
case tk_lw: process_load(0x20,4); break;
|
case tk_lwr: process_load(0x1D,0); break;
|
case tk_lwr: process_load(0x1D,0); break;
|
case tk_macro: process_macro(); break;
|
case tk_macro: process_macro(); break;
|
case tk_memdb: emit_insn(0x04400002,0,4); break;
|
case tk_memdb: emit_insn(0x04400002,!expand_flag,4); break;
|
case tk_memsb: emit_insn(0x04440002,0,4); break;
|
case tk_memsb: emit_insn(0x04440002,!expand_flag,4); break;
|
case tk_message: process_message(); break;
|
case tk_message: process_message(); break;
|
case tk_mod: process_rrop(0x16,0x2E); break;
|
case tk_mod: process_rrop(0x16,0x2E); break;
|
case tk_modu: process_rrop(0x14,-1); break;
|
case tk_modu: process_rrop(0x14,-1); break;
|
case tk_mov: process_mov(0x02, 0x22); break;
|
case tk_mov: process_mov(0x02, 0x22); break;
|
case tk_mul: process_rrop(0x3A,0x3A); break;
|
case tk_mul: process_rrop(0x3A,0x3A); break;
|
//case tk_mulh: process_rrop(0x26, 0x3A); break;
|
//case tk_mulh: process_rrop(0x26, 0x3A); break;
|
case tk_mulu: process_rrop(0x38,0x38); break;
|
case tk_mulu: process_rrop(0x38,0x38); break;
|
//case tk_muluh: process_rrop(0x24, 0x38); break;
|
//case tk_muluh: process_rrop(0x24, 0x38); break;
|
case tk_neg: process_neg(); break;
|
case tk_neg: process_neg(); break;
|
case tk_nop: emit_insn(0x1C,0,4); break;
|
case tk_nop: emit_insn(0x1C,!expand_flag,4); break;
|
case tk_not: process_rop(0x05); break;
|
case tk_not: process_rop(0x05); break;
|
// case tk_not: process_rop(0x07); break;
|
// case tk_not: process_rop(0x07); break;
|
case tk_or: process_rrop(0x09,0x09); break;
|
case tk_or: process_rrop(0x09,0x09); break;
|
case tk_ori: process_riop(0x09); break;
|
case tk_ori: process_riop(0x09); break;
|
case tk_org: process_org(); break;
|
case tk_org: process_org(); break;
|
case tk_plus: expand_flag = 1; break;
|
case tk_plus: compress_flag = 0; expand_flag = 1; break;
|
case tk_public: process_public(); break;
|
case tk_public: process_public(); break;
|
case tk_rodata:
|
case tk_rodata:
|
if (first_rodata) {
|
if (first_rodata) {
|
while(sections[segment].address & 4095)
|
while(sections[segment].address & 4095)
|
emitByte(0x00);
|
emitByte(0x00);
|
sections[1].address = sections[segment].address;
|
sections[1].address = sections[segment].address;
|
first_rodata = 0;
|
first_rodata = 0;
|
binstart = sections[1].index;
|
binstart = sections[1].index;
|
ca = sections[1].address;
|
ca = sections[1].address;
|
}
|
}
|
segment = rodataseg;
|
segment = rodataseg;
|
break;
|
break;
|
case tk_redor: process_rop(0x06); break;
|
case tk_redor: process_rop(0x06); break;
|
case tk_ret: process_ret(); break;
|
case tk_ret: process_ret(); break;
|
case tk_rex: process_rex(); break;
|
case tk_rex: process_rex(); break;
|
case tk_rol: process_shift(0x4); break;
|
case tk_rol: process_shift(0x4); break;
|
case tk_roli: process_shift(0xC); break;
|
case tk_roli: process_shift(0xC); break;
|
case tk_ror: process_shift(0x5); break;
|
case tk_ror: process_shift(0x5); break;
|
case tk_rori: process_shift(0xD); break;
|
case tk_rori: process_shift(0xD); break;
|
case tk_rti: process_iret(0xC8000002); break;
|
case tk_rti: process_iret(0xC8000002); break;
|
case tk_sb: process_store(0x15,0); break;
|
case tk_sb: process_store(0x15,0); break;
|
case tk_sc: process_store(0x24,1); break;
|
case tk_sc: process_store(0x24,1); break;
|
case tk_sei: process_sei(); break;
|
case tk_sei: process_sei(); break;
|
//case tk_seq: process_riop(0x1B,2); break;
|
//case tk_seq: process_riop(0x1B,2); break;
|
case tk_sf: process_lsfloat(0x2B,0x00); break;
|
case tk_sf: process_lsfloat(0x2B,0x00); break;
|
case tk_sge: process_setop(-6); break;
|
case tk_sge: process_setop(-6); break;
|
case tk_sgeu: process_setiop(-7); break;
|
case tk_sgeu: process_setiop(-7); break;
|
case tk_sgt: process_setiop(-0x2C); break;
|
case tk_sgt: process_setiop(-0x2C); break;
|
case tk_sgtu: process_setiop(-0x1C); break;
|
case tk_sgtu: process_setiop(-0x1C); break;
|
//case tk_slt: process_rrop(0x33,0x02,0x00); break;
|
//case tk_slt: process_rrop(0x33,0x02,0x00); break;
|
//case tk_sltu: process_rrop(0x33,0x03,0x00); break;
|
//case tk_sltu: process_rrop(0x33,0x03,0x00); break;
|
//case tk_slti: process_riop(0x13,0x02); break;
|
//case tk_slti: process_riop(0x13,0x02); break;
|
//case tk_sltui: process_riop(0x13,0x03); break;
|
//case tk_sltui: process_riop(0x13,0x03); break;
|
case tk_sh: process_store(0x24,2); break;
|
case tk_sh: process_store(0x24,2); break;
|
case tk_shl: process_shift(0x0); break;
|
case tk_shl: process_shift(0x0); break;
|
case tk_shli: process_shifti(0x8); break;
|
case tk_shli: process_shifti(0x8); break;
|
case tk_shr: process_shift(0x1); break;
|
case tk_shr: process_shift(0x1); break;
|
case tk_shri: process_shifti(0x9); break;
|
case tk_shri: process_shifti(0x9); break;
|
case tk_shru: process_shift(0x1); break;
|
case tk_shru: process_shift(0x1); break;
|
case tk_shrui: process_shifti(0x9); break;
|
case tk_shrui: process_shifti(0x9); break;
|
case tk_sle: process_setop(0x28); break;
|
case tk_sle: process_setop(0x28); break;
|
case tk_sleu: process_setop(0x29); break;
|
case tk_sleu: process_setop(0x29); break;
|
case tk_slt: process_setop(0x06); break;
|
case tk_slt: process_setop(0x06); break;
|
case tk_sltu: process_setop(0x07); break;
|
case tk_sltu: process_setop(0x07); break;
|
//case tk_sne: process_setiop(0x1B,3); break;
|
//case tk_sne: process_setiop(0x1B,3); break;
|
case tk_slli: process_shifti(0x8); break;
|
case tk_slli: process_shifti(0x8); break;
|
case tk_srai: process_shifti(0xB); break;
|
case tk_srai: process_shifti(0xB); break;
|
case tk_srli: process_shifti(0x9); break;
|
case tk_srli: process_shifti(0x9); break;
|
case tk_sub: process_rrop(0x05,-0x04); break;
|
case tk_sub: process_rrop(0x05,-0x04); break;
|
case tk_subi: process_riop(0x05); break;
|
case tk_subi: process_riop(0x05); break;
|
case tk_sv: process_sv(0x37); break;
|
case tk_sv: process_sv(0x37); break;
|
case tk_sw: process_store(0x24,4); break;
|
case tk_sw: process_store(0x24,4); break;
|
case tk_swc: process_store(0x17,0); break;
|
case tk_swc: process_store(0x17,0); break;
|
case tk_swap: process_rop(0x03); break;
|
case tk_swap: process_rop(0x03); break;
|
//case tk_swp: process_storepair(0x27); break;
|
//case tk_swp: process_storepair(0x27); break;
|
case tk_sxb: process_rop(0x1A); break;
|
case tk_sxb: process_rop(0x1A); break;
|
case tk_sxc: process_rop(0x19); break;
|
case tk_sxc: process_rop(0x19); break;
|
case tk_sxh: process_rop(0x18); break;
|
case tk_sxh: process_rop(0x18); break;
|
case tk_sync: emit_insn(0x04480002,0,4); break;
|
case tk_sync: emit_insn(0x04480002,!expand_flag,4); break;
|
//case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break;
|
//case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break;
|
case tk_vadd: process_vrrop(0x04); break;
|
case tk_vadd: process_vrrop(0x04); break;
|
case tk_vadds: process_vsrrop(0x14); break;
|
case tk_vadds: process_vsrrop(0x14); break;
|
case tk_vand: process_vrrop(0x08); break;
|
case tk_vand: process_vrrop(0x08); break;
|
case tk_vands: process_vsrrop(0x18); break;
|
case tk_vands: process_vsrrop(0x18); break;
|
case tk_vdiv: process_vrrop(0x3E); break;
|
case tk_vdiv: process_vrrop(0x3E); break;
|
case tk_vdivs: process_vsrrop(0x2E); break;
|
case tk_vdivs: process_vsrrop(0x2E); break;
|
case tk_vmov: process_vmov(0x02,0x33); break;
|
case tk_vmov: process_vmov(0x02,0x33); break;
|
case tk_vmul: process_vrrop(0x3A); break;
|
case tk_vmul: process_vrrop(0x3A); break;
|
case tk_vmuls: process_vsrrop(0x2A); break;
|
case tk_vmuls: process_vsrrop(0x2A); break;
|
case tk_vor: process_vrrop(0x09); break;
|
case tk_vor: process_vrrop(0x09); break;
|
case tk_vors: process_vsrrop(0x19); break;
|
case tk_vors: process_vsrrop(0x19); break;
|
case tk_vsub: process_vrrop(0x05); break;
|
case tk_vsub: process_vrrop(0x05); break;
|
case tk_vsubs: process_vsrrop(0x15); break;
|
case tk_vsubs: process_vsrrop(0x15); break;
|
case tk_vxor: process_vrrop(0x0A); break;
|
case tk_vxor: process_vrrop(0x0A); break;
|
case tk_vxors: process_vsrrop(0x1A); break;
|
case tk_vxors: process_vsrrop(0x1A); break;
|
case tk_xnor: process_rrop(0x0E,0x0E); break;
|
case tk_xnor: process_rrop(0x0E,0x0E); break;
|
case tk_xor: process_rrop(0x0A,0x0A); break;
|
case tk_xor: process_rrop(0x0A,0x0A); break;
|
case tk_xori: process_riop(0x0A); break;
|
case tk_xori: process_riop(0x0A); break;
|
case tk_zxb: process_rop(0x0A); break;
|
case tk_zxb: process_rop(0x0A); break;
|
case tk_zxc: process_rop(0x09); break;
|
case tk_zxc: process_rop(0x09); break;
|
case tk_zxh: process_rop(0x08); break;
|
case tk_zxh: process_rop(0x08); break;
|
case tk_id: process_label(); break;
|
case tk_id: process_label(); break;
|
case '-': compress_flag = 1; expand_flag = 0; break;
|
case '-': compress_flag = 1; expand_flag = 0; break;
|
}
|
}
|
NextToken();
|
NextToken();
|
}
|
}
|
j1:
|
j1:
|
;
|
;
|
}
|
}
|
|
|
|
|