/* coderx.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator Renesas RX */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "nls.h"
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmitree.h"
#include "codevars.h"
#include "codepseudo.h"
#include "headids.h"
#include "errmsg.h"
#include "ieeefloat.h"
#include "onoff_common.h"
#include "intpseudo.h"
#include "be_le.h"
#include "coderx.h"
/*---------------------------------------------------------------------------*/
/* Define this to use Renesas Assembler like pseudo instructions */
#define COMPAT
/*---------------------------------------------------------------------------*/
typedef enum
{
eRn
,
eDRn
,
eDRHn
,
eDRLn
,
eDCRn
} tRegType
;
typedef enum
{
eRXv1
,
eRXv2
,
eRXv3
} tInstSet
;
typedef struct
{
char Name
[7];
tInstSet InstSet
;
Boolean hasFloat
;
Boolean hasDouble
;
Word RegBank
;
Boolean hasMVTIPL
;
} tCPUProps
;
/*---------------------------------------------------------------------------*/
static const tCPUProps
*pCurrCPUProps
;
static tStrComp Temp1
;
static tStrComp Temp2
;
/*---------------------------------------------------------------------------*/
static Boolean ChkNoAttr
(void)
{
if (AttrPart.
str.
p_str[0])
{
WrError
(ErrNum_UseLessAttr
);
return False
;
}
return True
;
}
static Boolean CheckSup
(void)
{
if (SupAllowed
) return True
;
WrStrErrorPos
(ErrNum_PrivOrder
, &OpPart
);
return False
;
}
static Boolean CheckV2
(void)
{
if (pCurrCPUProps
->InstSet
>= eRXv2
) return True
;
WrError
(ErrNum_InstructionNotSupported
);
return False
;
}
static Boolean CheckV3
(void)
{
if (pCurrCPUProps
->InstSet
>= eRXv3
) return True
;
WrError
(ErrNum_InstructionNotSupported
);
return False
;
}
static Boolean CheckFloat
(void)
{
if (pCurrCPUProps
->hasFloat
) return True
;
WrError
(ErrNum_FPUNotEnabled
);
return False
;
}
static Boolean CheckDouble
(void)
{
if (pCurrCPUProps
->hasDouble
) return True
;
WrError
(ErrNum_FPUNotEnabled
);
return False
;
}
static const char *DCReg
[] = {
"DPSW",
"DCMR",
"DECNT",
"DEPC"
};
static Boolean DecodeReg
(const tStrComp
*pArg
, Byte
*pResult
, tRegType type
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
int i
;
int num
= 16;
switch (type
)
{
case eRn
:
if (as_strncasecmp
(str
, "R", 1)) return False
;
i
= 1;
break;
case eDRn
:
if (as_strncasecmp
(str
, "DR", 2)) return False
;
i
= 2;
break;
case eDRHn
:
if (as_strncasecmp
(str
, "DRH", 3)) return False
;
i
= 3;
break;
case eDRLn
:
if (as_strncasecmp
(str
, "DRL", 3)) return False
;
i
= 3;
break;
case eDCRn
:
for (i
= 0; i
< 4; i
++)
{
if (!as_strcasecmp
(str
, DCReg
[i
]))
{
*pResult
= i
;
return True
;
}
}
if (as_strncasecmp
(str
, "DCR", 3)) return False
;
i
= 3;
num
= 4;
break;
}
*pResult
= 0;
for (; i
< len
; i
++)
{
if (!isdigit(str
[i
])) return False
;
*pResult
= *pResult
* 10 + (str
[i
] - '0');
}
return *pResult
< num
;
}
static Boolean DecodeImm
(const tStrComp
*pArg
, LongInt
*pResult
, tSymbolFlags
*pFlags
)
{
const char *str
= pArg
->str.
p_str;
tStrComp ImmArg
;
Boolean ValOK
;
tSymbolFlags flags
;
if (str
[0] != '#') return False
;
StrCompRefRight
(&ImmArg
, pArg
, 1);
*pResult
= EvalStrIntExpressionWithFlags
(&ImmArg
, Int32
, &ValOK
, &flags
);
if (pFlags
) *pFlags
= flags
;
return ValOK
;
}
static Byte ImmSize32
(LongInt value
, tSymbolFlags flags
)
{
if (mFirstPassUnknown
(flags
)) return 0x00; /* Temporarily return maximum size */
if ((value
& 0xFFFFFF80) == 0xFFFFFF80 ||
(value
& 0xFFFFFF80) == 0x00000000) return 0x01; /* SIMM:8 */
if ((value
& 0xFFFF8000) == 0xFFFF8000 ||
(value
& 0xFFFF8000) == 0x00000000) return 0x02; /* SIMM:16 */
if ((value
& 0xFF800000) == 0xFF800000 ||
(value
& 0xFF800000) == 0x00000000) return 0x03; /* SIMM:24 */
return 0x00; /* IMM:32 */
}
static Byte ImmSize16
(LongInt value
, tSymbolFlags flags
)
{
if (mFirstPassUnknown
(flags
)) return 0x02; /* Temporarily return maximum size */
if ((value
& 0xFFFFFF80) == 0xFFFFFF80 ||
(value
& 0xFFFFFF80) == 0x00000000) return 0x01; /* SIMM:8 */
return 0x02; /* IMM:16 */
}
static int ImmOut
(int pos
, Byte size
, LongInt imm
)
{
int i
;
if (size
== 0x00) size
= 4;
for (i
= 0; i
< size
; i
++)
{
BAsmCode
[pos
+i
] = imm
& 0xFF;
imm
>>= 8;
}
return pos
+ size
;
}
static Boolean DecodeIndirectADC
(const tStrComp
*pArg
, Byte
*reg
, LongInt
*disp
, tSymbolFlags
*flags
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
int pos
;
Boolean ValOK
;
if (str
[len
-1] != ']') return False
;
for (pos
= len
- 2; pos
>= 0; pos
--)
{
if (str
[pos
] == '[') break;
}
if (pos
< 0) return False
;
StrCompCopySub
(&Temp1
, pArg
, pos
+ 1, len
- pos
- 2);
if (!DecodeReg
(&Temp1
, reg
, eRn
)) return False
;
if (pos
== 0)
{
*flags
= eSymbolFlag_None
;
*disp
= 0;
return True
;
}
StrCompCopySub
(&Temp1
, pArg
, 0, pos
);
*disp
= EvalStrIntExpressionWithFlags
(&Temp1
, UInt20
, &ValOK
, flags
);
return ValOK
;
}
static Byte DispSize
(LongInt disp
, tSymbolFlags flags
, Byte scale
)
{
Byte size
= 0;
Byte mask
= scale
- 1;
UNUSED
(flags
);
if (disp
& mask
)
{
WrStrErrorPos
(ErrNum_NotAligned
, &ArgStr
[1]);
return 0;
}
disp
/= scale
;
if (disp
== 0) size
= 0x00;
else if (disp
< 0) size
= 0xFF;
else if (disp
< 256) size
= 0x01;
else if (disp
< 65536) size
= 0x02;
else size
= 0xFF;
return size
;
}
static int DispOut
(int pos
, Byte size
, LongInt disp
, Byte scale
)
{
int i
;
disp
/= scale
;
if (size
> 0x02) size
= 0x00;
for (i
= 0; i
< size
; i
++ )
{
BAsmCode
[pos
+i
] = disp
& 0xFF;
disp
>>= 8;
}
return pos
+ size
;
}
static Boolean DecodeIndirectADD
(const tStrComp
*pArg
, Byte
*reg
, LongInt
*disp
, tSymbolFlags
*flags
, Byte
*memex
, Byte
*scale
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
if (len
> 2 && str
[len
-2] == '.')
{
switch (as_toupper
(str
[len
-1]))
{
case 'B':
*memex
= 0x00;
*scale
= 1;
break;
case 'W':
*memex
= 0x01;
*scale
= 2;
break;
case 'L':
*memex
= 0x02;
*scale
= 4;
break;
default:
return False
;
}
StrCompCopySub
(&Temp2
, pArg
, 0, len
- 2);
pArg
= &Temp2
;
}
else if (len
> 3 && str
[len
-3] == '.' && as_toupper
(str
[len
-2]) == 'U')
{
switch (as_toupper
(str
[len
-1]))
{
case 'B':
*memex
= 0x80;
*scale
= 1;
break;
case 'W':
*memex
= 0x03;
*scale
= 2;
break;
default:
return False
;
}
StrCompCopySub
(&Temp2
, pArg
, 0, len
- 3);
pArg
= &Temp2
;
}
return DecodeIndirectADC
(pArg
, reg
, disp
, flags
);
}
static Boolean DecodeFloat
(const tStrComp
*pArg
, LongInt
*pResult
)
{
const char *str
= pArg
->str.
p_str;
tStrComp ImmArg
;
TempResult temp
;
Boolean Result
= True
;
if (str
[0] != '#') return False
;
StrCompRefRight
(&ImmArg
, pArg
, 1);
as_tempres_ini
(&temp
);
EvalStrExpression
(&ImmArg
, &temp
);
switch (temp.
Typ)
{
case TempInt
:
*pResult
= temp.
Contents.
Int;
break;
case TempFloat
:
Double_2_ieee4
(temp.
Contents.
Float, (unsigned char *)pResult
, False
);
/* TODO: rework this - we should better pass in a byte array as pResult */
if (HostBigEndian
)
DSwap
(pResult
, 4);
break;
default:
Result
= False
;
}
as_tempres_free
(&temp
);
return Result
;
}
static Boolean DecodeIndirectL
(const tStrComp
*pArg
, Byte
*reg
, LongInt
*disp
, tSymbolFlags
*flags
)
{
Boolean result
;
Byte memex
= 0x02; /* L */
Byte scale
;
result
= DecodeIndirectADD
(pArg
, reg
, disp
, flags
, &memex
, &scale
);
if (result
&& memex
!= 0x02) result
= False
;
return result
;
}
static tSymbolSize DecodeAttrSize
(void)
{
switch (strlen(AttrPart.
str.
p_str))
{
case 0:
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return eSymbolSizeUnknown
;
case 1:
switch (AttrPart.
str.
p_str[0])
{
case 'B':
return eSymbolSize8Bit
;
case 'W':
return eSymbolSize16Bit
;
case 'L':
return eSymbolSize32Bit
;
default:
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return eSymbolSizeUnknown
;
}
default:
WrStrErrorPos
(ErrNum_TooLongAttr
, &AttrPart
);
return eSymbolSizeUnknown
;
}
}
static Boolean DecodeRelative
(const tStrComp
*pArg
, Byte
*reg
, LongInt
*disp
, tSymbolFlags
*flags
)
{ /* dsp:5[Rn] (R0-R7) */
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
int pos
;
Boolean ValOK
;
if (str
[len
-1] != ']') return False
;
for (pos
= len
- 2; pos
> 0; pos
--)
{
if (str
[pos
] == '[') break;
}
if (pos
< 1) return False
;
StrCompCopySub
(&Temp1
, pArg
, pos
+ 1, len
- pos
- 2);
if (!DecodeReg
(&Temp1
, reg
, eRn
)) return False
;
if (*reg
> 7) return False
;
StrCompCopySub
(&Temp1
, pArg
, 0, pos
);
*disp
= EvalStrIntExpressionWithFlags
(&Temp1
, UInt20
, &ValOK
, flags
);
return ValOK
;
}
static int Size2Scale
(Byte size
)
{
Byte scale
;
switch (size
)
{
case 0x00: /* B */
scale
= 1;
break;
case 0x01: /* W */
scale
= 2;
break;
case 0x02: /* L */
scale
= 4;
break;
default:
return -1;
}
return scale
;
}
static Boolean ChkDisp5
(Byte size
, LongInt disp
, tSymbolFlags flags
)
{
const int scale
= Size2Scale
(size
);
if (scale
< 0) return False
;
if (!mFirstPassUnknown
(flags
))
{
if (disp
& (scale
- 1))
{
WrError
(ErrNum_AddrMustBeAligned
);
return False
;
}
if (disp
/ scale
> 31 || disp
< 0) return False
;
}
return True
;
}
static Byte DispSize5
(Byte size
, LongInt disp
)
{
const Byte scale
= Size2Scale
(size
);
return disp
/ scale
;
}
static Boolean DecodeIndexed
(tStrComp
*pArg
, Byte
*regi
, Byte
*regb
)
{ /* [Ri,Rb] */
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
int pos
;
if (str
[0] != '[' || str
[len
-1] != ']') return False
;
for (pos
= 2; pos
< len
- 2; pos
++)
{
if (str
[pos
] == ',') break;
}
StrCompCopySub
(&Temp1
, pArg
, 1, pos
- 1);
if (!DecodeReg
(&Temp1
, regi
, eRn
)) return False
;
StrCompCopySub
(&Temp1
, pArg
, pos
+ 1, len
- pos
- 2);
if (!DecodeReg
(&Temp1
, regb
, eRn
)) return False
;
return True
;
}
static Boolean DecodeIncDec
(tStrComp
*pArg
, Byte
*reg
, Byte
*id
)
{ /* [Rn+] / [-Rn]] */
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
if (len
< 5) return False
;
if (str
[0] != '[' || str
[len
-1] != ']') return False
;
if (str
[len
-2] == '+')
{
*id
= 0x00;
StrCompCopySub
(&Temp1
, pArg
, 1, len
- 3);
}
else if (str
[1] == '-')
{
*id
= 0x01;
StrCompCopySub
(&Temp1
, pArg
, 2, len
- 3);
}
else return False
;
return DecodeReg
(&Temp1
, reg
, eRn
);
}
static Boolean DecodeRegRange
(tStrComp
*pArg
, Byte
*range
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
Byte reg1
;
Byte reg2
;
int pos
;
if (len
< 5) return False
;
for (pos
= 2; pos
< len
- 2; pos
++)
{
if (str
[pos
] == '-') break;
}
if (pos
>= len
- 2) return False
;
StrCompCopySub
(&Temp1
, pArg
, 0, pos
);
if (!DecodeReg
(&Temp1
, ®1
, eRn
)) return False
;
StrCompCopySub
(&Temp1
, pArg
, pos
+ 1, len
- pos
- 1);
if (!DecodeReg
(&Temp1
, ®2
, eRn
)) return False
;
if (reg1
== 0 || reg1
>= reg2
) return False
;
*range
= (reg1
<< 4) | reg2
;
return True
;
}
static Boolean DecodeIndirect
(tStrComp
*pArg
, Byte
*reg
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
if (str
[0] != '[') return False
;
if (str
[len
-1] != ']') return False
;
StrCompCopySub
(&Temp1
, pArg
, 1, len
- 2);
if (!DecodeReg
(&Temp1
, reg
, eRn
)) return False
;
return True
;
}
static Boolean DecodeAcc
(tStrComp
*pArg
, Byte
*acc
)
{
const char *str
= pArg
->str.
p_str;
const int len
= strlen(str
);
if (len
!= 2) return False
;
if (as_toupper
(str
[0]) != 'A') return False
;
if (str
[1] != '0' && str
[1] != '1') return False
;
*acc
= str
[1] - '0';
return True
;
}
static Boolean DecodeAttrDouble
(Byte
*size
)
{
if (strlen(AttrPart.
str.
p_str) != 1)
{
WrStrErrorPos
(ErrNum_TooLongAttr
, &AttrPart
);
return False
;
}
switch (as_toupper
(AttrPart.
str.
p_str[0]))
{
case 'L':
*size
= 0;
break;
case 'D':
*size
= 1;
break;
default:
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return False
;
}
return True
;
}
/*---------------------------------------------------------------------------*/
static void DecodeABS
(Word Index
)
{
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,2)) return;
if (ArgCnt
== 1)
{
Byte reg
;
if (!DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0x7E;
BAsmCode
[1] = (Index
>> 8) | reg
;
CodeLen
= 2;
}
else
{
Byte regs
;
Byte regd
;
if (!DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = Index
& 0xFF;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
}
}
static void DecodeADC
(Word Index
)
{
Byte regs
;
Byte regd
;
Byte size
;
LongInt imm
;
tSymbolFlags flags
;
LongInt disp
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if ((Index
& 0x0800) && DecodeImm
(&ArgStr
[1], &imm
, &flags
)) /* ADC only */
{
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x70 | (size
<< 2);
BAsmCode
[2] = 0x20 | regd
;
CodeLen
= ImmOut
(3, size
, imm
);
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0x03 | (Index
>> 8);
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
if (DecodeIndirectL
(&ArgStr
[1], ®s
, &disp
, &flags
))
{
if (mFirstPassUnknown
(flags
)) size
= 0x02;
else size
= DispSize
(disp
, flags
, 4);
BAsmCode
[0] = 0x06;
BAsmCode
[1] = 0xA0 | size
;
BAsmCode
[2] = Index
& 0xFF;
BAsmCode
[3] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(4, size
, disp
, 4);
}
}
static const struct {
Byte OpcImm4
; /* #IMM:4,Rd */
Byte OpcImm1
; /* #IMM:*(,Rs),Rd 1st byte */
Byte OpcImm2
; /* 2nd byte */
Byte Opc2
; /* Rs,Rd / [Rs].UB,Rd */
Byte Opc3
; /* Rs,Rs2,Rd */
Byte Opc4
; /* [Rs],Rd */
Byte flags
; /* 1<<0:, 1<<1:, 1<<2:#UIMM8 1<<3:Rs,Rs,Rd */
} OpTabADD
[] = {
{ 0x62, 0x70, 0x00, 0x48, 0x20, 0x08, 0x0B }, /* ADD */
{ 0x64, 0x74, 0x20, 0x50, 0x40, 0x10, 0x09 }, /* AND */
{ 0x61, 0x74, 0x00, 0x44, 0, 0x04, 0x05 }, /* CMP */
{ 0x63, 0x74, 0x10, 0x4C, 0x30, 0x0C, 0x09 }, /* MUL */
{ 0x65, 0x74, 0x30, 0x54, 0x50, 0x14, 0x09 }, /* OR */
{ 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08 }, /* SUB */
};
static void DecodeADD
(Word Index
)
{
Byte regs1
;
Byte regs2
;
Byte regd
;
Byte size
;
LongInt imm
;
tSymbolFlags flags
;
LongInt disp
;
Byte memex
;
Byte scale
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,3)) return;
if (!DecodeReg
(&ArgStr
[2], ®s2
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if (ArgCnt
== 2)
regd
= regs2
;
else
{
if (!DecodeReg
(&ArgStr
[3], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[3]);
return;
}
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (ArgCnt
== 2 && !mFirstPassUnknown
(flags
) && imm
>= 0 && imm
< 16 )
{ /* #UIMM:4 */
BAsmCode
[0] = OpTabADD
[Index
].
OpcImm4;
BAsmCode
[1] = (imm
<< 4) | regd
;
CodeLen
= 2;
return;
}
if ((OpTabADD
[Index
].
flags & 0x04) && ArgCnt
== 2 &&
!mFirstPassUnknown
(flags
) && imm
>= 0 && imm
< 256)
{ /* #UIMM:8 */
BAsmCode
[0] = 0x75;
BAsmCode
[1] = 0x50 | regd
;
BAsmCode
[2] = imm
;
CodeLen
= 3;
return;
}
if (((OpTabADD
[Index
].
flags & 0x01) && ArgCnt
== 2) || (OpTabADD
[Index
].
flags & 0x02))
{ /* #SIMM:* */
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = OpTabADD
[Index
].
OpcImm1 | size
;
if (OpTabADD
[Index
].
flags & 0x02)
if (ArgCnt
== 2)
BAsmCode
[1] = (regd
<< 4) | regd
; /* #Imm,Rd */
else
BAsmCode
[1] = (regs2
<< 4) | regd
; /* #imm,Rs,Rd */
else
BAsmCode
[1] = OpTabADD
[Index
].
OpcImm2 | regd
;
CodeLen
= ImmOut
(2, size
, imm
);
return;
}
}
if (DecodeReg
(&ArgStr
[1], ®s1
, eRn
))
{ /* Rs */
if (ArgCnt
== 2)
{
BAsmCode
[0] = OpTabADD
[Index
].
Opc2 | 0x03;
BAsmCode
[1] = (regs1
<< 4) | regd
;
CodeLen
= 2;
}
else if (OpTabADD
[Index
].
flags & 0x08)
{
BAsmCode
[0] = 0xFF;
BAsmCode
[1] = OpTabADD
[Index
].
Opc3 | regd
;
BAsmCode
[2] = (regs1
<< 4) | regs2
;
CodeLen
= 3;
}
else WrStrErrorPos
(ErrNum_TooManyArgs
, &ArgStr
[3]);
return;
}
if (ArgCnt
== 2 && DecodeIndirectADD
(&ArgStr
[1], ®s1
, &disp
, &flags
, &memex
, &scale
))
{
if (memex
== 0x80)
{
size
= DispSize
(disp
, flags
, 1);
BAsmCode
[0] = OpTabADD
[Index
].
Opc2 | size
;
BAsmCode
[1] = (regs1
<< 4) | regd
;
CodeLen
= DispOut
(2, size
, disp
, 1);
return;
}
size
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0x06;
BAsmCode
[1] = OpTabADD
[Index
].
Opc4 | (memex
<< 6) | size
;
BAsmCode
[2] = (regs1
<< 4) | regd
;
CodeLen
= DispOut
(3, size
, disp
, scale
);
return;
}
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
}
static const struct {
Byte OpcIM1
; /* Imm3,[Rd] */
Byte OpcIM2
;
Byte OpcRM
; /* Rs,[Rd] / Rs,Rd */
Byte OpcIR
; /* #Imm5,Rd */
Byte flags
;
} OpTabBCLR
[] = {
{ 0xF0, 0x08, 0x64, 0x7A, 0x00 }, /* BCLR */
{ 0xF0, 0x00, 0x6C, 0, 0x01 }, /* BNOT */
{ 0xF0, 0x00, 0x60, 0x78, 0x00 }, /* BSET */
{ 0xF4, 0x00, 0x68, 0x7C, 0x00 }, /* BTST */
};
static void DecodeBCLR
(Word Index
)
{
Byte regs
;
Byte regd
;
Byte size
;
Byte memex
;
Byte scale
;
LongInt imm
;
LongInt disp
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
memex
= 0;
if (DecodeIndirectADD
(&ArgStr
[2], ®d
, &disp
, &flags
, &memex
, &scale
))
{
if (memex
)
{
WrStrErrorPos
(ErrNum_InvOpSize
, &ArgStr
[2]);
return;
}
size
= DispSize
(disp
, flags
, 1);
if (size
> 0x02){
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mSymbolQuestionable
(flags
) && (imm
< 0 || imm
> 7))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
if (OpTabBCLR
[Index
].
flags & 0x01)
{ /* BNOT */
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0xE0 | (imm
<< 2) | size
;
BAsmCode
[2] = 0x0F | (regd
<< 4);
CodeLen
= DispOut
(3, size
, disp
, 1);
}
else
{ /* BCLR, BSET, BTST */
BAsmCode
[0] = OpTabBCLR
[Index
].
OpcIM1 | size
;
BAsmCode
[1] = OpTabBCLR
[Index
].
OpcIM2 | (regd
<< 4) | imm
;
CodeLen
= DispOut
(2, size
, disp
, 1);
}
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabBCLR
[Index
].
OpcRM | size
;
BAsmCode
[2] = regs
| (regd
<< 4);
CodeLen
= DispOut
(3, size
, disp
, 1);
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[1]);
}
else if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mSymbolQuestionable
(flags
) && (imm
< 0 || imm
> 31))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
if (OpTabBCLR
[Index
].
flags & 0x01)
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0xE0 | imm
;
BAsmCode
[2] = 0xF0 | regd
;
CodeLen
= 3;
}
else
{
BAsmCode
[0] = OpTabBCLR
[Index
].
OpcIR | (imm
>> 4);
BAsmCode
[1] = ((imm
& 0x0F) << 4) | regd
;
CodeLen
= 2;
}
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabBCLR
[Index
].
OpcRM | 0x03;
BAsmCode
[2] = regs
| (regd
<< 4);
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[1]);
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
static void DecodeBCnd
(Word Index
)
{
const char *str
= AttrPart.
str.
p_str;
const int len
= strlen(str
);
Byte attr
= 0;
Byte reg
;
LongInt addr
;
tSymbolFlags flags
;
Boolean ValOK
;
LongInt disp
;
if (len
> 1)
{
WrStrErrorPos
(ErrNum_TooLongAttr
, &AttrPart
);
return;
}
if (len
== 1)
{
attr
= as_toupper
(str
[0]);
switch (attr
)
{
case 'S':
break;
case 'B':
break;
case 'W':
break;
case 'A':
case 'L':
if (Index
!= 14)
{
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return;
}
break;
default:
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return;
}
}
if (!ChkArgCnt
(1,1)) return;
if ((attr
== 0 || attr
== 'L') && DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = 0x7F;
BAsmCode
[1] = 0x40 | reg
;
CodeLen
= 2;
return;
}
addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int32
, &ValOK
, &flags
);
if (ValOK
)
{
if (attr
== 'L')
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
disp
= addr
- EProgCounter
();
/* Try 3 bit */
if ((attr
== 0 || attr
== 'S') && disp
>= 3 && disp
<= 10)
{
if (disp
> 7) disp
-= 8;
if (Index
== 0 || Index
== 1)
{
BAsmCode
[0] = 0x10 | (Index
<< 3) | disp
;
CodeLen
= 1;
return;
}
if (Index
== 14)
{
BAsmCode
[0] = 0x08 | disp
;
CodeLen
= 1;
return;
}
WrError
(ErrNum_InternalError
);
}
if (attr
== 'S' && !mFirstPassUnknownOrQuestionable
(flags
))
{
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
return;
}
/* Try 8 bit */
if ((attr
== 0 || attr
== 'B') &&
((disp
& 0xFFFFFF80) == 0xFFFFFF80 ||
(disp
& 0xFFFFFF80) == 0x00000000))
{
BAsmCode
[0] = 0x20 | Index
;
BAsmCode
[1] = disp
& 0xFF;
CodeLen
= 2;
return;
}
if (attr
== 'B' && !mFirstPassUnknownOrQuestionable
(flags
))
{
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
return;
}
/* Try 16 bit */
if ((attr
== 0 || attr
== 'W') &&
((disp
& 0xFFFF8000) == 0xFFFF8000 ||
(disp
& 0xFFFF8000) == 0x00000000))
{
if (Index
== 0 || Index
== 1)
{
BAsmCode
[0] = 0x3A | Index
;
BAsmCode
[1] = disp
& 0xFF;
BAsmCode
[2] = (disp
>> 8) & 0xFF;
CodeLen
= 3;
return;
}
if (Index
== 14)
{
BAsmCode
[0] = 0x38;
BAsmCode
[1] = disp
& 0xFF;
BAsmCode
[2] = (disp
>> 8) & 0xFF;
CodeLen
= 3;
return;
}
WrError
(ErrNum_JmpDistTooBig
);
return;
}
if (attr
== 'W' && !mFirstPassUnknownOrQuestionable
(flags
))
{
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
return;
}
/* Try 24 bit */
if ((disp
& 0xFF800000) == 0xFF800000 ||
(disp
& 0xFF800000) == 0x00000000)
{
if (Index
== 14)
{
BAsmCode
[0] = 0x04;
BAsmCode
[1] = disp
& 0xFF;
BAsmCode
[2] = (disp
>> 8) & 0xFF;
BAsmCode
[3] = (disp
>> 16) & 0xFF;
CodeLen
= 4;
return;
}
}
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
}
}
static void DecodeBMCnd
(Word Index
)
{
Byte regd
;
Byte size
;
Byte memex
;
Byte scale
;
LongInt imm
;
LongInt disp
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
memex
= 0;
if (DecodeIndirectADD
(&ArgStr
[2], ®d
, &disp
, &flags
, &memex
, &scale
))
{
if (memex
)
{
WrStrErrorPos
(ErrNum_InvOpSize
, &ArgStr
[2]);
return;
}
size
= DispSize
(disp
, flags
, 1);
if (size
> 0x02){
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[2]);
return;
}
}
else if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
size
= 0x03;
}
else
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (size
< 0x03)
{
/* #imm,disp[Rd] */
if (!mSymbolQuestionable
(flags
) && (imm
< 0 || imm
> 7))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0xE0 | (imm
<< 2) | size
;
BAsmCode
[2] = (regd
<< 4) | Index
;
CodeLen
= DispOut
(3, size
, disp
, 1);
return;
}
else
{
/* #imm,Rd */
if (!mSymbolQuestionable
(flags
) && (imm
< 0 || imm
> 31))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0xE0 | imm
;
BAsmCode
[2] = (Index
<< 4) | regd
;
CodeLen
= 3;
return;
}
}
WrError
(ErrNum_OverRange
);
}
static void DecodeBRK
(Word Index
)
{
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(0,0)) return;
BAsmCode
[0] = Index
;
CodeLen
= 1;
}
static void DecodeBSR
(Word Index
)
{
const char *str
= AttrPart.
str.
p_str;
const int len
= strlen(str
);
Byte attr
= 0;
Byte reg
;
LongInt addr
;
tSymbolFlags flags
;
Boolean ValOK
;
LongInt disp
;
UNUSED
(Index
);
if (len
> 1)
{
WrStrErrorPos
(ErrNum_TooLongAttr
, &AttrPart
);
return;
}
if (len
== 1)
{
attr
= as_toupper
(str
[0]);
switch (attr
)
{
case 'W':
case 'A':
case 'L':
break;
default:
WrStrErrorPos
(ErrNum_UndefAttr
, &AttrPart
);
return;
}
}
if (!ChkArgCnt
(1,1)) return;
if ((attr
== 0 || attr
== 'L') && DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = 0x7F;
BAsmCode
[1] = 0x50 | reg
;
CodeLen
= 2;
return;
}
addr
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int32
, &ValOK
, &flags
);
if (ValOK
)
{
if (attr
== 'L')
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
disp
= addr
- EProgCounter
();
/* Try 16 bit */
if ((attr
== 0 || attr
== 'W') &&
((disp
& 0xFFFF8000) == 0xFFFF8000 ||
(disp
& 0xFFFF8000) == 0x00000000))
{
BAsmCode
[0] = 0x39;
BAsmCode
[1] = disp
& 0xFF;
BAsmCode
[2] = (disp
>> 8) & 0xFF;
CodeLen
= 3;
return;
}
if (attr
== 'W' && !mFirstPassUnknownOrQuestionable
(flags
))
{
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
return;
}
/* Try 24 bit */
if ((disp
& 0xFF800000) == 0xFF800000 ||
(disp
& 0xFF800000) == 0x00000000)
{
BAsmCode
[0] = 0x05;
BAsmCode
[1] = disp
& 0xFF;
BAsmCode
[2] = (disp
>> 8) & 0xFF;
BAsmCode
[3] = (disp
>> 16) & 0xFF;
CodeLen
= 4;
return;
}
WrStrErrorPos
(ErrNum_JmpDistTooBig
, &ArgStr
[1]);
}
}
static const char *BitPSW
[] = {
"C", "Z", "S", "O", NULL
, NULL
, NULL
, NULL
,
"I", "U", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
static void DecodeCLRPSW
(Word Index
)
{
int i
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
for (i
= 0; i
< 16; i
++)
{
if (BitPSW
[i
] && !as_strcasecmp
(ArgStr
[1].
str.
p_str, BitPSW
[i
])) break;
}
if (i
< 16)
{
BAsmCode
[0] = 0x7F;
BAsmCode
[1] = Index
| i
;
CodeLen
= 2;
}
else WrStrErrorPos
(ErrNum_UnknownFlag
, &ArgStr
[1]);
}
static const struct {
Byte OpcI
;
Byte Opc2
;
Byte OpcM
;
} OpTabDIV
[] = {
{ 0x80, 0x20, 0x08 }, /* DIV */
{ 0x90, 0x24, 0x09 }, /* DIVU */
{ 0x60, 0x18, 0x06 }, /* EMUL */
{ 0x70, 0x1C, 0x07 }, /* EMULU */
{ 0x40, 0x10, 0x04 }, /* MAX */
{ 0x50, 0x14, 0x05 }, /* MIN */
};
static void DecodeDIV
(Word Index
)
{
Byte regs
;
Byte regd
;
Byte size
;
LongInt imm
;
tSymbolFlags flags
;
LongInt disp
;
Byte memex
;
Byte scale
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x70 | (size
<< 2);
BAsmCode
[2] = OpTabDIV
[Index
].
OpcI | regd
;
CodeLen
= ImmOut
(3, size
, imm
);
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabDIV
[Index
].
Opc2 | 0x03;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
if (DecodeIndirectADD
(&ArgStr
[1], ®s
, &disp
, &flags
, &memex
, &scale
))
{
if (memex
== 0x80)
{
size
= DispSize
(disp
, flags
, 1);
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabDIV
[Index
].
Opc2 | size
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(3, size
, disp
, 1);
return;
}
size
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0x06;
BAsmCode
[1] = 0x20 | (memex
<< 6) | size
;
BAsmCode
[2] = OpTabDIV
[Index
].
OpcM;
BAsmCode
[3] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(4, size
, disp
, scale
);
return;
}
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
}
static const struct {
Byte OpcI
;
Byte OpcM
;
Byte Opc3
;
Byte flags
;
} OpTabFADD
[] = {
{ 0x20, 0x88, 0xA0, 0x03 }, /* FADD */
{ 0x10, 0x84, 0, 0x01 }, /* FCMP */
{ 0x40, 0x90, 0, 0x01 }, /* FDIV */
{ 0x30, 0x8C, 0xB0, 0x03 }, /* FMUL */
{ 0x00, 0x80, 0x80, 0x03 }, /* FSUB */
{ 0, 0x94, 0, 0x00 }, /* FTOI */
{ 0, 0x98, 0, 0x00 }, /* ROUND */
{ 0, 0xA0, 0, 0x10 }, /* FSQRT */
{ 0, 0xA4, 0, 0x10 }, /* FTOU */
};
static void DecodeFADD
(Word Index
)
{
Byte regs
;
Byte regd
;
Byte size
;
LongInt imm
;
LongInt disp
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!CheckFloat
()) return;
if ((OpTabFADD
[Index
].
flags & 0x02) && ArgCnt
== 3)
{
Byte regs2
;
if (!DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®s2
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
if (!DecodeReg
(&ArgStr
[3], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[3]);
return;
}
BAsmCode
[0] = 0xFF;
BAsmCode
[1] = OpTabFADD
[Index
].
Opc3 | regd
;
BAsmCode
[2] = (regs
<< 4) | regs2
;
CodeLen
= 3;
return;
}
if (!ChkArgCnt
(2,2)) return;
if (OpTabFADD
[Index
].
flags & 0x10)
{
if (!CheckV2
()) return;
}
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if ((OpTabFADD
[Index
].
flags & 0x01) &&
DecodeFloat
(&ArgStr
[1], &imm
))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x72;
BAsmCode
[2] = OpTabFADD
[Index
].
OpcI | regd
;
CodeLen
= ImmOut
(3, 0, imm
); /* size==0 means 4 byte */
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
size
= 0x03;
disp
= 0;
}
else if (DecodeIndirectL
(&ArgStr
[1], ®s
, &disp
, &flags
))
{
if (mFirstPassUnknown
(flags
)) size
= 0x02;
else size
= DispSize
(disp
, flags
, 4);
}
else
{
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabFADD
[Index
].
OpcM | size
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(3, size
, disp
, 4);
}
static void DecodeINT
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mFirstPassUnknown
(flags
) && (imm
< -128 || imm
> 255))
{
WrStrErrorPos
(ErrNum_ArgOutOfRange
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0x75;
BAsmCode
[1] = 0x60;
BAsmCode
[2] = imm
& 0xFF;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
Byte flags
;
} OpTabITOF
[] = {
{ 0x44, 0x11, 0x00 }, /* ITOF */
{ 0x54, 0x15, 0x10 }, /* UTOF */
};
static void DecodeITOF
(Word Index
)
{
Byte regs
;
Byte regd
;
Byte size
;
Byte memex
;
Byte scale
;
LongInt disp
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!CheckFloat
()) return;
if ((OpTabITOF
[Index
].
flags & 0x10) && !CheckV2
()) return;
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
size
= 0x03;
disp
= 0;
memex
= 0;
}
else if (DecodeIndirectADD
(&ArgStr
[1], ®s
, &disp
, &flags
, &memex
, &scale
))
{
if (mFirstPassUnknown
(flags
)) size
= 0x02;
else size
= DispSize
(disp
, flags
, scale
);
}
else
{
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
return;
}
if (memex
== 0x80 || size
== 0x03)
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabITOF
[Index
].
Opc1 | size
;
BAsmCode
[2] = (regs
<< 4) | regd
;
if (size
< 0x03) CodeLen
= DispOut
(3, size
, disp
, scale
);
else CodeLen
= 3;
return;
}
BAsmCode
[0] = 0x06;
BAsmCode
[1] = 0x20 | (memex
<< 6) | size
;
BAsmCode
[2] = OpTabITOF
[Index
].
Opc2;
BAsmCode
[3] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(4, size
, disp
, scale
);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
} OpTabJMP
[] = {
{ 0x7F, 0x00 }, /* JMP */
{ 0x7F, 0x10 }, /* JSR */
{ 0x7E, 0xB0 }, /* POP */
{ 0x7E, 0x50 }, /* ROLC */
{ 0x7E, 0x40 }, /* RORC */
{ 0x7E, 0x30 }, /* SAT */
};
static void DecodeJMP
(Word Index
)
{
Byte reg
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
if (DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = OpTabJMP
[Index
].
Opc1;
BAsmCode
[1] = OpTabJMP
[Index
].
Opc2 | reg
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
}
static const struct {
Byte Opc
;
Byte flags
;
} OpTabMACHI
[] = {
{ 0x04, 0x01 }, /* MACHI */
{ 0x05, 0x01 }, /* MACLO */
{ 0x00, 0x01 }, /* MULHI */
{ 0x01, 0x01 }, /* MULLO */
{ 0x67, 0x00 }, /* REVL */
{ 0x65, 0x00 }, /* REVW */
{ 0x07, 0x11 }, /* EMACA */
{ 0x47, 0x11 }, /* EMSBA */
{ 0x03, 0x11 }, /* EMULA */
{ 0x06, 0x11 }, /* MACLH */
{ 0x44, 0x11 }, /* MSBHI */
{ 0x46, 0x11 }, /* MSBLH */
{ 0x45, 0x11 }, /* MSBLO */
{ 0x02, 0x11 }, /* MULLH */
};
static void DecodeMACHI
(Word Index
)
{
Byte reg1
;
Byte reg2
;
Byte acc
= 0;
if ((OpTabMACHI
[Index
].
flags & 0x10) && !CheckV2
()) return;
if (!ChkNoAttr
()) return;
if (pCurrCPUProps
->InstSet
== eRXv1
)
{
if (!ChkArgCnt
(2,2)) return;
}
else
{
if (OpTabMACHI
[Index
].
flags & 0x01)
{
if (!ChkArgCnt
(3,3)) return;
if (!DecodeAcc
(&ArgStr
[3], &acc
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[3]);
return;
}
}
else
{
if (!ChkArgCnt
(2,2)) return;
}
}
if (!DecodeReg
(&ArgStr
[1], ®1
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®2
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabMACHI
[Index
].
Opc | (acc
<< 3);
BAsmCode
[2] = (reg1
<< 4) | reg2
;
CodeLen
= 3;
}
static void DecodeMOV
(Word Index
)
{
tSymbolSize size
;
Byte regs
;
Byte regd
;
LongInt imm
;
LongInt disp
;
tSymbolFlags flags
;
tSymbolFlags flags2
;
Byte disp2
;
Byte isize
;
Byte dsize
;
Byte scale
;
Byte regi
;
UNUSED
(Index
);
size
= DecodeAttrSize
();
if (size
== eSymbolSizeUnknown
) return;
scale
= Size2Scale
(size
);
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
) && regs
< 8 &&
DecodeRelative
(&ArgStr
[2], ®d
, &disp
, &flags
))
{ /* (1) */
if (ChkDisp5
(size
, disp
, flags
))
{
disp2
= DispSize5
(size
, disp
);
BAsmCode
[0] = 0x80 | (size
<< 4) | ((disp2
>> 2) & 0x07);
BAsmCode
[1] = ((disp2
<< 6) & 0x80) | (regd
<< 4) | ((disp2
<< 3) & 0x08) | regs
;
CodeLen
= 2;
return;
}
}
if (DecodeRelative
(&ArgStr
[1], ®s
, &disp
, &flags
) &&
DecodeReg
(&ArgStr
[2], ®d
, eRn
) && regd
< 8)
{ /* (2) */
if (ChkDisp5
(size
, disp
, flags
))
{
disp2
= DispSize5
(size
, disp
);
BAsmCode
[0] = 0x88 | (size
<< 4) | ((disp2
>> 2) & 0x07);
BAsmCode
[1] = ((disp2
<< 6) & 0x80) | (regs
<< 4) | ((disp2
<< 3) & 0x08) | regd
;
CodeLen
= 2;
return;
}
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (size
== 0x02 && DecodeReg
(&ArgStr
[2], ®d
, eRn
) &&
!mFirstPassUnknown
(flags
) && imm
>= 0 && imm
< 16)
{ /* (3) */
BAsmCode
[0] = 0x66;
BAsmCode
[1] = (imm
<< 4) | regd
;
CodeLen
= 2;
return;
}
if (DecodeRelative
(&ArgStr
[2], ®d
, &disp
, &flags
))
{ /* (4) */
if ((size
== 0x00 && imm
>= -128 && imm
< 256) ||
(size
!= 0x00 && imm
>= 0 && imm
< 256))
{
disp2
= DispSize5
(size
, disp
);
BAsmCode
[0] = 0x3C | size
;
BAsmCode
[1] = ((disp2
<< 3) & 0x80) | (regd
<< 4) | (disp2
& 0x0F);
BAsmCode
[2] = imm
;
CodeLen
= 3;
return;
}
}
if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
if (size
== 0x02 && !mFirstPassUnknown
(flags
) &&
imm
>= 0 && imm
< 256)
{ /* (5) */
BAsmCode
[0] = 0x75;
BAsmCode
[1] = 0x40 | regd
;
BAsmCode
[2] = imm
;
CodeLen
= 3;
return;
}
/* (6) */
isize
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFB;
BAsmCode
[1] = (regd
<< 4) | (isize
<< 2) | 0x02;
CodeLen
= ImmOut
(2, isize
, imm
);
return;
}
if (DecodeIndirectADC
(&ArgStr
[2], ®d
, &disp
, &flags2
))
{ /* (8) */
switch (size
)
{
case 0x00: /* B */
if (imm
< -128 || imm
> 255)
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
isize
= 0x01;
break;
case 0x01: /* W */
if (imm
< -32768 || imm
> 65535)
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
isize
= ImmSize16
(imm
, flags
);
break;
case 0x02: /* L */
isize
= ImmSize32
(imm
, flags
);
break;
default:
WrError
(ErrNum_InternalError
);
return;
}
dsize
= DispSize
(disp
, flags2
, scale
);
BAsmCode
[0] = 0xF8 | dsize
;
BAsmCode
[1] = (regd
<< 4) | (isize
<< 2) | size
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
CodeLen
= ImmOut
(CodeLen
, isize
, imm
);
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{ /* (7) */
BAsmCode
[0] = 0xCF | (size
<< 4);
BAsmCode
[1] = (regs
<< 4) | regd
;
CodeLen
= 2;
return;
}
if (DecodeIndirectADC
(&ArgStr
[2], ®d
, &disp
, &flags
))
{ /* (11) */
dsize
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0xC3 | (size
<< 4) | (dsize
<< 2);
BAsmCode
[1] = (regd
<< 4) | regs
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
return;
}
if (DecodeIndexed
(&ArgStr
[2], ®i
, ®d
))
{ /* (12) */
BAsmCode
[0] = 0xFE;
BAsmCode
[1] = (size
<< 4) | regi
;
BAsmCode
[2] = (regd
<< 4) | regs
;
CodeLen
= 3;
return;
}
if (DecodeIncDec
(&ArgStr
[2], ®d
, ®i
))
{ /* (14) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x20 | (regi
<< 2) | size
;
BAsmCode
[2] = (regd
<< 4) | regs
;
CodeLen
= 3;
return;
}
}
if (DecodeIndirectADC
(&ArgStr
[1], ®s
, &disp
, &flags
))
{
if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{ /* (9) */
dsize
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0xCC | (size
<< 4) | dsize
;
BAsmCode
[1] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
return;
}
if (DecodeIndirectADC
(&ArgStr
[2], ®d
, &imm
, &flags2
))
{ /* (13) */
dsize
= DispSize
(disp
, flags
, scale
); /* src */
isize
= DispSize
(imm
, flags2
, scale
); /* dst */
BAsmCode
[0] = 0xC0 | (size
<< 4) | (isize
<< 2) | dsize
;
BAsmCode
[1] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
CodeLen
= DispOut
(CodeLen
, isize
, imm
, scale
);
return;
}
}
if (DecodeIndexed
(&ArgStr
[1], ®i
, ®s
) &&
DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{ /* (10) */
BAsmCode
[0] = 0xFE;
BAsmCode
[1] = 0x40 | (size
<< 4) | regi
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
if (DecodeIncDec
(&ArgStr
[1], ®s
, ®i
) &&
DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x28 | (regi
<< 2) | size
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[1]);
}
static void DecodeMOVU
(Word Index
)
{
tSymbolSize size
;
Byte regs
;
Byte regd
;
Byte scale
;
LongInt disp
;
tSymbolFlags flags
;
Byte disp2
;
Byte dsize
;
Byte regi
;
UNUSED
(Index
);
size
= DecodeAttrSize
();
if (size
== eSymbolSizeUnknown
|| size
== eSymbolSize32Bit
) return;
scale
= Size2Scale
(size
);
if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
if (DecodeRelative
(&ArgStr
[1], ®s
, &disp
, &flags
) &&
ChkDisp5
(size
, disp
, flags
) && regd
< 8)
{ /* (1) */
disp2
= DispSize5
(size
, disp
);
BAsmCode
[0] = 0xB0 | (size
<< 3) | ((disp2
>> 2) & 0x07);
BAsmCode
[1] = ((disp2
<< 6) & 0x80) | (regs
<< 4) | ((disp2
<< 3) & 0x08) | regd
;
CodeLen
= 2;
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{ /* (2)-1 */
BAsmCode
[0] = 0x5B | (size
<< 2);
BAsmCode
[1] = (regs
<< 4) | regd
;
CodeLen
= 2;
return;
}
if (DecodeIndirectADC
(&ArgStr
[1], ®s
, &disp
, &flags
))
{ /* (2)-2 */
dsize
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0x58 | (size
<< 2) | dsize
;
BAsmCode
[1] = (regs
<< 4) | regd
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
return;
}
if (DecodeIndexed
(&ArgStr
[1], ®i
, ®s
))
{ /* (3) */
BAsmCode
[0] = 0xFE;
BAsmCode
[1] = 0xC0 | (size
<< 4) | regi
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
if (DecodeIncDec
(&ArgStr
[1], ®s
, ®i
))
{ /* (4) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x38 | (regi
<< 2) | size
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
}
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
}
static const struct {
Byte Opc2
;
Byte Opc3
;
Byte flags
;
} OpTabMVFACHI
[] = {
{ 0x1E, 0x00, 0x00 }, /* MVFACHI */
{ 0x1E, 0x20, 0x00 }, /* MVFACMI */
{ 0x1E, 0x30, 0x10 }, /* MVFACGU */
{ 0x1E, 0x10, 0x10 }, /* MVFACLO */
};
static void DecodeMVFACHI
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
Byte acc
;
Byte reg
;
if ((OpTabMVFACHI
[Index
].
flags & 0x10) && !CheckV2
()) return;
if (!ChkNoAttr
()) return;
if (pCurrCPUProps
->InstSet
== eRXv1
)
{
if (!ChkArgCnt
(1,1)) return;
imm
= 0x02;
acc
= 0x00;
}
else
{
if (!ChkArgCnt
(3,3)) return;
if (!DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
WrStrErrorPos
(ErrNum_OnlyImmAddr
, &ArgStr
[1]);
return;
}
switch (imm
)
{
case 0:
imm
= 0x02;
break;
case 1:
imm
= 0x03;
break;
case 2:
imm
= 0x00;
break;
default:
if (mSymbolQuestionable
(flags
)) break;
WrStrErrorPos
(ErrNum_ArgOutOfRange
, &ArgStr
[1]);
return;
}
if (!DecodeAcc
(&ArgStr
[2], &acc
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
}
if (!DecodeReg
(&ArgStr
[ArgCnt
], ®
, eRn
))
{
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[ArgCnt
]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabMVFACHI
[Index
].
Opc2 | ((imm
>> 1) & 0x01);
BAsmCode
[2] = OpTabMVFACHI
[Index
].
Opc3 | (acc
<< 7) | ((imm
<< 6) & 0x40) | reg
;
CodeLen
= 3;
}
static const char *SPReg
[] = {
"PSW", "PC", "USP", "FPSW", NULL
, NULL
, NULL
, NULL
,
"BPSW", "BPC", "ISP", "FINTV", "INTB", "EXTB", NULL
, NULL
,
};
static void DecodeMVFC
(Word Index
)
{
Byte reg
;
size_t i
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (DecodeReg
(&ArgStr
[2], ®
, eRn
))
{
for (i
= 0; i
< as_array_size
(SPReg
); i
++)
{
if (i
== 13 && pCurrCPUProps
->InstSet
== eRXv1
)
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
}
if (SPReg
[i
] && !as_strcasecmp
(SPReg
[i
], ArgStr
[1].
str.
p_str))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x6A;
BAsmCode
[2] = (i
<< 4) | reg
;
CodeLen
= 3;
return;
}
}
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[1]);
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
static const struct {
Byte Opc2
;
Byte Opc3
;
Byte flags
;
} OpTabMVTACHI
[] = {
{ 0x17, 0x00, 0x00 }, /* MVTACHI */
{ 0x17, 0x10, 0x00 }, /* MVTACLO */
{ 0x17, 0x30, 0x10 }, /* MVTACGU */
};
static void DecodeMVTACHI
(Word Index
)
{
Byte acc
;
Byte reg
;
if ((OpTabMVTACHI
[Index
].
flags & 0x10) && !CheckV2
()) return;
if (!ChkNoAttr
()) return;
if (pCurrCPUProps
->InstSet
== eRXv1
)
{
if (!ChkArgCnt
(1,1)) return;
acc
= 0x00;
}
else
{
if (!ChkArgCnt
(2,2)) return;
if (!DecodeAcc
(&ArgStr
[2], &acc
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
}
if (!DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
WrStrErrorPos
(ErrNum_AddrModeNotSupported
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabMVTACHI
[Index
].
Opc2;
BAsmCode
[2] = OpTabMVTACHI
[Index
].
Opc3 | (acc
<< 7) | reg
;
CodeLen
= 3;
}
static void DecodeMVTC
(Word Index
)
{
Byte reg
;
LongInt imm
;
Byte size
;
tSymbolFlags flags
;
size_t i
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
for (i
= 0; i
< as_array_size
(SPReg
); i
++)
{
if (SPReg
[i
] && !as_strcasecmp
(SPReg
[i
], ArgStr
[2].
str.
p_str))
{
if (i
== 1)
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
return;
}
if (i
== 13 && pCurrCPUProps
->InstSet
== eRXv1
)
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x73 | (size
<< 2);
BAsmCode
[2] = i
;
CodeLen
= ImmOut
(3, size
, imm
);
return;
}
if (DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x68;
BAsmCode
[2] = (reg
<< 4) | i
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[1]);
}
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
static void DecodeMVTIPL
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
UNUSED
(Index
);
if (!CheckSup
()) return;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
if (!pCurrCPUProps
->hasMVTIPL
)
{
WrError
(ErrNum_InstructionNotSupported
);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mFirstPassUnknown
(flags
) && (imm
< 0 || imm
> 15))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0x75;
BAsmCode
[1] = 0x70;
BAsmCode
[2] = imm
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
static const Byte OpTabPOPC
[] = {
0xE0, /* POPC */
0xC0, /* PUSHC */
};
static void DecodePOPC
(Word Index
)
{
size_t i
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
for (i
= 0; i
< as_array_size
(SPReg
); i
++)
{
if (SPReg
[i
] && !as_strcasecmp
(SPReg
[i
], ArgStr
[1].
str.
p_str))
{
if (Index
== 0 && i
== 1)
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[1]);
return;
}
if (i
== 13 && pCurrCPUProps
->InstSet
== eRXv1
)
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[2]);
}
BAsmCode
[0] = 0x7E;
BAsmCode
[1] = OpTabPOPC
[Index
] | i
;
CodeLen
= 2;
return;
}
}
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[1]);
}
static const Byte OpTabPOPM
[] = {
0x6F, /* POPM */
0x6E, /* PUSHM */
};
static void DecodePOPM
(Word Index
)
{
Byte range
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
if (DecodeRegRange
(&ArgStr
[1], &range
))
{
BAsmCode
[0] = OpTabPOPM
[Index
];
BAsmCode
[1] = range
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvRegList
, &ArgStr
[1]);
}
static void DecodePUSH
(Word Index
)
{
tSymbolSize size
;
Byte reg
;
LongInt disp
;
tSymbolFlags flags
;
Byte dsize
;
Byte scale
;
UNUSED
(Index
);
size
= DecodeAttrSize
();
if (size
== eSymbolSizeUnknown
) return;
if (!ChkArgCnt
(1,1)) return;
scale
= Size2Scale
(size
);
if (DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = 0x7E;
BAsmCode
[1] = 0x80 | (size
<< 4) | reg
;
CodeLen
= 2;
return;
}
if (DecodeIndirectADC
(&ArgStr
[1], ®
, &disp
, &flags
))
{
dsize
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0xF4 | dsize
;
BAsmCode
[1] = 0x08 | (reg
<< 4) | size
;
CodeLen
= DispOut
(2, dsize
, disp
, scale
);
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[1]);
}
static const struct {
Byte Opc2
;
Byte Opc3
;
Byte flags
;
} OpTabRACW
[] = {
{ 0x18, 0x00, 0x00 }, /* RACW */
{ 0x19, 0x00, 0x10 }, /* RACL */
{ 0x19, 0x40, 0x10 }, /* RDACL */
{ 0x18, 0x40, 0x10 }, /* RDACW */
};
static void DecodeRACW
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
Byte acc
= 0;
if ((OpTabRACW
[Index
].
flags & 0x10) && !CheckV2
()) return;
if (!ChkNoAttr
()) return;
if (pCurrCPUProps
->InstSet
== eRXv1
)
{
if (!ChkArgCnt
(1,1)) return;
}
else
{
if (!ChkArgCnt
(2,2)) return;
if (!DecodeAcc
(&ArgStr
[2], &acc
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (mFirstPassUnknown
(flags
) || imm
== 1 || imm
== 2)
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabRACW
[Index
].
Opc2;
BAsmCode
[2] = OpTabRACW
[Index
].
Opc3 | (acc
<< 7) | ((imm
- 1) << 4);
CodeLen
= 3;
return;
}
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[1]);
}
static void DecodeRMPA
(Word Index
)
{
tSymbolSize size
;
size
= DecodeAttrSize
();
if (size
== eSymbolSizeUnknown
) return;
if (!ChkArgCnt
(0,0)) return;
BAsmCode
[0] = 0x7F;
BAsmCode
[1] = Index
| size
;
CodeLen
= 2;
}
static const struct {
Byte Opc1
;
Byte Opc2
;
} OpTabROTL
[] = {
{ 0x6E, 0x66 }, /* ROTL */
{ 0x6C, 0x64 }, /* ROTR */
};
static void DecodeROTL
(Word Index
)
{
Byte regs
;
Byte regd
;
LongInt imm
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mFirstPassUnknown
(flags
) && (imm
< 0 || imm
> 31))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabROTL
[Index
].
Opc1 | ((imm
>> 4) & 0x01);
BAsmCode
[2] = ((imm
<< 4) & 0xF0) | regd
;
CodeLen
= 3;
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabROTL
[Index
].
Opc2;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
}
static void DecodeRTE
(Word Index
)
{
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(0,0)) return;
switch (Index
)
{
case 0x7F95: /* RTE */
case 0x7F94: /* RTFI */
case 0x7F96: /* WAIT */
if (!CheckSup
()) return;
}
BAsmCode
[0] = Index
>> 8;
BAsmCode
[1] = Index
;
CodeLen
= 2;
}
static void DecodeRTSD
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
Byte range
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,2)) return;
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (mSymbolQuestionable
(flags
) && (imm
< 0 || imm
> 255))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
if (ArgCnt
== 2 && DecodeRegRange
(&ArgStr
[2], &range
))
{
BAsmCode
[0] = 0x3F;
BAsmCode
[1] = range
;
BAsmCode
[2] = imm
;
CodeLen
= 3;
return;
}
if (ArgCnt
> 1)
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0x67;
BAsmCode
[1] = imm
;
CodeLen
= 2;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static void DecodeSCCnd
(Word Index
)
{
tSymbolSize size
;
Byte reg
;
LongInt disp
;
tSymbolFlags flags
;
Byte dsize
;
Byte scale
;
size
= DecodeAttrSize
();
if (size
== eSymbolSizeUnknown
) return;
if (!ChkArgCnt
(1,1)) return;
scale
= Size2Scale
(size
);
if (DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
if (size
!= 0x02)
{
WrStrErrorPos
(ErrNum_InvOpSize
, &ArgStr
[1]);
return;
}
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0xD3 | (size
<< 2);
BAsmCode
[2] = (reg
<< 4) | Index
;
CodeLen
= 3;
return;
}
if (DecodeIndirectADC
(&ArgStr
[1], ®
, &disp
, &flags
))
{
dsize
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0xD0 | (size
<< 2) | dsize
;
BAsmCode
[2] = (reg
<< 4) | Index
;
CodeLen
= DispOut
(3, dsize
, disp
, scale
);
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
Byte Opc3
;
} OpTabSHAR
[] = {
{ 0x6A, 0x61, 0xA0 }, /* SHAR */
{ 0x6C, 0x62, 0xC0 }, /* SHLL */
{ 0x68, 0x60, 0x80 }, /* SHLR */
};
static void DecodeSHAR
(Word Index
)
{
Byte regs
;
Byte regd
;
LongInt imm
;
tSymbolFlags flags
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,3)) return;
if (!DecodeReg
(&ArgStr
[ArgCnt
], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvRegName
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!mFirstPassUnknown
(flags
) && (imm
< 0 || imm
> 31))
{
WrStrErrorPos
(ErrNum_OverRange
, &ArgStr
[1]);
return;
}
if (ArgCnt
== 3)
{
if (DecodeReg
(&ArgStr
[2], ®s
, eRn
))
{ /* (3) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabSHAR
[Index
].
Opc3 | imm
;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvAddrMode
, &ArgStr
[2]);
return;
}
/* (1) */
BAsmCode
[0] = OpTabSHAR
[Index
].
Opc1 | (imm
>> 4);
BAsmCode
[1] = ((imm
<< 4) & 0xF0) | regd
;
CodeLen
= 2;
return;
}
if (ArgCnt
> 2)
{
WrStrErrorPos
(ErrNum_TooManyArgs
, &ArgStr
[2]);
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{ /* (2) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = OpTabSHAR
[Index
].
Opc2;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static const struct {
Byte OpcIR
;
Byte OpcRR
;
} OpTabSTNZ
[] = {
{ 0xF0, 0x4F }, /* STNZ */
{ 0xE0, 0x4B }, /* STZ */
};
static void DecodeSTNZ
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
Byte regd
;
Byte regs
;
Byte size
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x70 | (size
<< 2);
BAsmCode
[2] = OpTabSTNZ
[Index
].
OpcIR | regd
;
CodeLen
= ImmOut
(3, size
, imm
);
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
if (!CheckV2
()) return;
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabSTNZ
[Index
].
OpcRR;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
Byte Opc3
;
Byte flags
;
} OpTabTST
[] = {
{ 0xC0, 0x30, 0x0C, 0x01 }, /* TST */
{ 0, 0x40, 0x10, 0x00 }, /* XCHG */
{ 0xD0, 0x34, 0x0D, 0x03 }, /* XOR */
};
static void DecodeTST
(Word Index
)
{
Byte reg1
;
Byte reg2
;
LongInt imm
;
LongInt disp
;
tSymbolFlags flags
;
Byte size
;
Byte memex
;
Byte scale
;
if (!ChkNoAttr
()) return;
if ((OpTabTST
[Index
].
flags & 0x02) && ArgCnt
== 3)
{
Byte reg3
;
if (!CheckV3
()) return;
if (!DecodeReg
(&ArgStr
[1], ®1
, eRn
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®2
, eRn
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if (!DecodeReg
(&ArgStr
[3], ®3
, eRn
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[3]);
return;
}
BAsmCode
[0] = 0xFF;
BAsmCode
[1] = 0x60 | reg3
;
BAsmCode
[2] = (reg1
<< 4) | reg2
;
CodeLen
= 3;
return;
}
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[2], ®2
, eRn
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
if ((OpTabTST
[Index
].
flags & 0x01) &&
DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
size
= ImmSize32
(imm
, flags
);
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x70 | (size
<< 2);
BAsmCode
[2] = OpTabTST
[Index
].
Opc1 | reg2
;
CodeLen
= ImmOut
(3, size
, imm
);
return;
}
if (DecodeReg
(&ArgStr
[1], ®1
, eRn
))
{
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabTST
[Index
].
Opc2 | 0x03;
BAsmCode
[2] = (reg1
<< 4) | reg2
;
CodeLen
= 3;
return;
}
if (DecodeIndirectADD
(&ArgStr
[1], ®1
, &disp
, &flags
, &memex
, &scale
))
{
if (memex
== 0x80)
{
size
= DispSize
(disp
, flags
, 1);
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabTST
[Index
].
Opc2 | size
;
BAsmCode
[2] = (reg1
<< 4) | reg2
;
CodeLen
= DispOut
(3, size
, disp
, 1);
return;
}
size
= DispSize
(disp
, flags
, scale
);
BAsmCode
[0] = 0x06;
BAsmCode
[1] = 0x20 | (memex
<< 6) | size
;
BAsmCode
[2] = OpTabTST
[Index
].
Opc3;
BAsmCode
[3] = (reg1
<< 4) | reg2
;
CodeLen
= DispOut
(4, size
, disp
, scale
);
return;
}
}
static void DecodeMOVCO
(Word Index
)
{
Byte regs
;
Byte regd
;
UNUSED
(Index
);
if (!CheckV2
()) return;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeIndirect
(&ArgStr
[2], ®d
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x27;
BAsmCode
[2] = (regd
<< 4) | regs
;
CodeLen
= 3;
}
static void DecodeMOVLI
(Word Index
)
{
Byte regs
;
Byte regd
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!DecodeIndirect
(&ArgStr
[1], ®s
))
{
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x2F;
BAsmCode
[2] = (regs
<< 4) | regd
;
CodeLen
= 3;
}
static const Byte OpTabBFMOV
[] = {
0x5E, /* BFMOV */
0x5A, /* BFMOVZ */
};
static void DecodeBFMOV
(Word Index
)
{
LongInt slsb
;
LongInt dlsb
;
LongInt width
;
tSymbolFlags flags
;
Byte regs
;
Byte regd
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(5,5)) return;
if (!CheckV3
()) return;
if (!DecodeImm
(&ArgStr
[1], &slsb
, &flags
))
{
WrStrErrorPos
(ErrNum_ExpectInt
, &ArgStr
[1]);
return;
}
if (!mFirstPassUnknownOrQuestionable
(flags
) && !ChkRange
(slsb
, 0, 31)) return;
if (!DecodeImm
(&ArgStr
[2], &dlsb
, &flags
))
{
WrStrErrorPos
(ErrNum_ExpectInt
, &ArgStr
[2]);
return;
}
if (!mFirstPassUnknownOrQuestionable
(flags
) && !ChkRange
(dlsb
, 0, 31)) return;
if (!DecodeImm
(&ArgStr
[3], &width
, &flags
))
{
WrStrErrorPos
(ErrNum_ExpectInt
, &ArgStr
[3]);
return;
}
if (!mFirstPassUnknownOrQuestionable
(flags
) && !ChkRange
(width
, 1, 31)) return;
if (!DecodeReg
(&ArgStr
[4], ®s
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[4]);
return;
}
if (!DecodeReg
(&ArgStr
[5], ®d
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[5]);
return;
}
if (slsb
+ width
> 32 || dlsb
+ width
> 32)
{
WrError
(ErrNum_OverRange
);
return;
}
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = OpTabBFMOV
[Index
];
BAsmCode
[2] = (regs
<< 4) | regd
;
BAsmCode
[3] = ((dlsb
- slsb
) & 0x1f) | ((dlsb
<< 5) & 0xE0);
BAsmCode
[4] = ((dlsb
>> 3) & 0x03) | (((dlsb
+ width
) << 2) & 0x7C);
CodeLen
= 5;
}
static const struct {
Byte OpcI
;
Byte OpcR
;
} OpTabRSTR
[] = {
{ 0xF0, 0xD0 }, /* RSTR */
{ 0xE0, 0xC0 }, /* SAVE */
};
static void DecodeRSTR
(Word Index
)
{
LongInt imm
;
tSymbolFlags flags
;
Byte reg
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
if (!CheckV3
()) return;
if (!pCurrCPUProps
->RegBank
)
{
WrError
(ErrNum_InstructionNotSupported
);
return;
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (!ChkRange
(imm
, 0, pCurrCPUProps
->RegBank
- 1)) return;
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x76;
BAsmCode
[2] = OpTabRSTR
[Index
].
OpcI;
BAsmCode
[3] = imm
;
CodeLen
= 4;
return;
}
if (DecodeReg
(&ArgStr
[1], ®
, eRn
))
{
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x76;
BAsmCode
[2] = OpTabRSTR
[Index
].
OpcR | reg
;
BAsmCode
[3] = 0x00;
CodeLen
= 4;
return;
}
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
} OpTabDABS
[] = {
{ 0x0C, 0x01 }, /* DABS */
{ 0x0C, 0x02 }, /* DNEG */
{ 0x0D, 0x0D }, /* DROUND */
{ 0x0D, 0x00 }, /* DSQRT */
{ 0x0D, 0x0C }, /* DTOF */
{ 0x0D, 0x08 }, /* DTOI */
{ 0x0D, 0x09 }, /* DTOU */
};
static void DecodeDABS
(Word Index
)
{
Byte regs
;
Byte regd
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeReg
(&ArgStr
[1], ®s
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®d
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0x76;
BAsmCode
[1] = 0x90;
BAsmCode
[2] = OpTabDABS
[Index
].
Opc1 | (regs
<< 4);
BAsmCode
[3] = OpTabDABS
[Index
].
Opc2 | (regd
<< 4);
CodeLen
= 4;
}
static const struct {
Byte Opc
;
} OpTabDADD
[] = {
{ 0x00 }, /* DADD */
{ 0x05 }, /* DDIV */
{ 0x02 }, /* DMUL */
{ 0x01 }, /* DSUB */
};
static void DecodeDADD
(Word Index
)
{
Byte regs1
;
Byte regs2
;
Byte regd
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(3,3)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeReg
(&ArgStr
[1], ®s1
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®s2
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
if (!DecodeReg
(&ArgStr
[3], ®d
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[3]);
return;
}
BAsmCode
[0] = 0x76;
BAsmCode
[1] = 0x90;
BAsmCode
[2] = OpTabDADD
[Index
].
Opc | (regs2
<< 4);
BAsmCode
[3] = (regd
<< 4) | regs1
;
CodeLen
= 4;
}
static void DecodeDCMPcm
(Word Index
)
{
Byte regs1
;
Byte regs2
;
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeReg
(&ArgStr
[1], ®s1
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®s2
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0x76;
BAsmCode
[1] = 0x90;
BAsmCode
[2] = 0x08 | (regs2
<< 4);
BAsmCode
[3] = ((Index
<< 4) & 0xF0) | regs1
;
CodeLen
= 4;
}
static void DecodeDMOV
(Word Index
)
{
Byte size
;
Byte regs
;
Byte regd
;
LongInt disp
;
LongInt imm
;
tSymbolFlags flags
;
Byte dsize
;
UNUSED
(Index
);
if (!ChkArgCnt
(2,2)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeAttrDouble
(&size
)) return;
if (DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
if (DecodeReg
(&ArgStr
[2], ®d
, eDRHn
))
{ /* (1) / (2) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x77;
BAsmCode
[2] = 0x80 | regs
;
BAsmCode
[3] = 0x02 | (regd
<< 4) | size
;
CodeLen
= 4;
return;
}
if (DecodeReg
(&ArgStr
[2], ®d
, eDRLn
) && !size
)
{ /* (3) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x77;
BAsmCode
[2] = 0x80 | regs
;
BAsmCode
[3] = 0x00 | (regd
<< 4);
CodeLen
= 4;
return;
}
}
if (DecodeReg
(&ArgStr
[2], ®d
, eRn
))
{
if (DecodeReg
(&ArgStr
[1], ®s
, eDRHn
) && !size
)
{ /* (4) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x75;
BAsmCode
[2] = 0x80 | regd
;
BAsmCode
[3] = 0x02 | (regs
<< 4);
CodeLen
= 4;
return;
}
if (DecodeReg
(&ArgStr
[1], ®s
, eDRLn
) && !size
)
{ /* (5) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x75;
BAsmCode
[2] = 0x80 | regd
;
BAsmCode
[3] = 0x00 | (regs
<< 4);
CodeLen
= 4;
return;
}
}
if (DecodeReg
(&ArgStr
[1], ®s
, eDRn
) && size
)
{
if (DecodeReg
(&ArgStr
[2], ®d
, eDRn
))
{ /* (6) */
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x90;
BAsmCode
[2] = 0x0C | (regs
<< 4);
BAsmCode
[3] = 0x00 | (regd
<< 4);
CodeLen
= 4;
return;
}
if (DecodeIndirectADC
(&ArgStr
[2], ®d
, &disp
, &flags
) && size
)
{ /* (7) */
dsize
= DispSize
(disp
, flags
, 8);
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0x78 | dsize
;
BAsmCode
[2] = 0x08 | (regd
<< 4);
CodeLen
= DispOut
(3, dsize
, disp
, 8);
BAsmCode
[CodeLen
++] = 0x00 | (regs
<< 4);
return;
}
}
if (DecodeIndirectADC
(&ArgStr
[1], ®s
, &disp
, &flags
) && size
)
{
if (DecodeReg
(&ArgStr
[2], ®d
, eDRn
))
{ /* (8) */
dsize
= DispSize
(disp
, flags
, 8);
BAsmCode
[0] = 0xFC;
BAsmCode
[1] = 0xC8 | dsize
;
BAsmCode
[2] = 0x08 | (regs
<< 4);
CodeLen
= DispOut
(3, dsize
, disp
, 8);
BAsmCode
[CodeLen
++] = 0x00 | (regd
<< 4);
return;
}
}
if (DecodeImm
(&ArgStr
[1], &imm
, &flags
))
{
if (DecodeReg
(&ArgStr
[2], ®d
, eDRHn
))
{ /* (9) / (10) */
BAsmCode
[0] = 0xF9;
BAsmCode
[1] = 0x03;
BAsmCode
[2] = 0x02 | (regd
<< 4) | size
;
CodeLen
= ImmOut
(3, 0, imm
);
return;
}
if (DecodeReg
(&ArgStr
[2], ®d
, eDRLn
) && !size
)
{ /* (11) */
BAsmCode
[0] = 0xF9;
BAsmCode
[1] = 0x03;
BAsmCode
[2] = 0x00 | (regd
<< 4);
CodeLen
= ImmOut
(3, 0, imm
);
return;
}
}
WrError
(ErrNum_InvArg
);
}
static const Byte OpTabDPOPM
[] = {
0xA8, /* DPOPM */
0xA0 /* DPUSHM */
};
static void DecodeDPOPM
(Word Index
)
{
const int len
= strlen(ArgStr
[1].
str.
p_str);
Byte size
;
Byte reg1
;
Byte reg2
;
int i
;
if (!DecodeAttrDouble
(&size
)) return;
if (!ChkArgCnt
(1,1)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
for (i
= 0; i
< len
; i
++)
{
if (ArgStr
[1].
str.
p_str[i
] == '-') break;
}
if (i
>= len
)
{
WrStrErrorPos
(ErrNum_InvRegList
, &ArgStr
[1]);
return;
}
StrCompCopySub
(&Temp1
, &ArgStr
[1], 0, i
);
if (!DecodeReg
(&Temp1
, ®1
, size
? eDRn
: eDCRn
))
{
WrStrErrorPos
(ErrNum_InvRegList
, &ArgStr
[1]);
return;
}
StrCompCopySub
(&Temp1
, &ArgStr
[1], i
+ 1, len
- i
- 1);
if (!DecodeReg
(&Temp1
, ®2
, size
? eDRn
: eDCRn
))
{
WrStrErrorPos
(ErrNum_InvRegList
, &ArgStr
[1]);
return;
}
if (reg2
>= reg1
)
{
BAsmCode
[0] = 0x75;
BAsmCode
[1] = OpTabDPOPM
[Index
] | (size
<< 4);
BAsmCode
[2] = (reg1
<< 4) | (reg2
- reg1
);
CodeLen
= 3;
return;
}
WrStrErrorPos
(ErrNum_InvRegList
, &ArgStr
[1]);
}
static const struct {
Byte Opc1
;
Byte Opc2
;
} OpTabFTOD
[] = {
{ 0x80, 0x0A }, /* FTOD */
{ 0x80, 0x09 }, /* ITOD */
{ 0x80, 0x0D }, /* UTOD */
};
static void DecodeFTOD
(Word Index
)
{
Byte regs
;
Byte regd
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeReg
(&ArgStr
[1], ®s
, eRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[1]);
return;
}
if (!DecodeReg
(&ArgStr
[2], ®d
, eDRn
))
{
WrStrErrorPos
(ErrNum_ExpectReg
, &ArgStr
[2]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x77;
BAsmCode
[2] = OpTabFTOD
[Index
].
Opc1 | regs
;
BAsmCode
[3] = OpTabFTOD
[Index
].
Opc2 | (regd
<< 4);
CodeLen
= 4;
}
static void DecodeMVFDC
(Word Index
)
{
Byte regc
;
Byte reg
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(2,2)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
if (!DecodeReg
(&ArgStr
[Index
+ 1], ®c
, eDCRn
))
{
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[Index
+ 1]);
return;
}
if (!DecodeReg
(&ArgStr
[2 - Index
], ®
, eRn
))
{
WrStrErrorPos
(ErrNum_InvReg
, &ArgStr
[2 - Index
]);
return;
}
BAsmCode
[0] = 0xFD;
BAsmCode
[1] = 0x75 | (Index
<< 1);
BAsmCode
[2] = 0x80 | reg
;
BAsmCode
[3] = 0x04 | (regc
<< 4);
CodeLen
= 4;
}
static void DecodeMVFDR
(Word Index
)
{
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(0,0)) return;
if (!CheckV3
()) return;
if (!CheckDouble
()) return;
BAsmCode
[0] = 0x75;
BAsmCode
[1] = 0x90;
BAsmCode
[2] = 0x1B;
CodeLen
= 3;
}
#ifdef COMPAT
#define BigEndianSymName "BIGENDIAN" /* T.B.D. */
static void DecodeENDIAN
(Word Index
)
{
const char *str
;
UNUSED
(Index
);
if (!ChkNoAttr
()) return;
if (!ChkArgCnt
(1,1)) return;
str
= ArgStr
[1].
str.
p_str;
if (!as_strcasecmp
(str
, "BIG"))
SetFlag
(&TargetBigEndian
, BigEndianSymName
, True
);
else if (!as_strcasecmp
(str
, "LITTLE"))
SetFlag
(&TargetBigEndian
, BigEndianSymName
, False
);
else
WrStrErrorPos
(ErrNum_InvArg
, &ArgStr
[1]);
}
static void DecodeWORD
(Word flags
)
{
DecodeIntelDW
(flags
| (TargetBigEndian
? eIntPseudoFlag_BigEndian
: 0));
}
static void DecodeLWORD
(Word flags
)
{
DecodeIntelDD
(flags
| (TargetBigEndian
? eIntPseudoFlag_BigEndian
: 0));
}
static void DecodeFLOAT
(Word flags
)
{
DecodeIntelDD
(flags
| (TargetBigEndian
? eIntPseudoFlag_BigEndian
: 0));
}
static void DecodeDOUBLE
(Word flags
)
{
DecodeIntelDQ
(flags
| (TargetBigEndian
? eIntPseudoFlag_BigEndian
: 0));
}
#endif /* COMPAT */
/*---------------------------------------------------------------------------*/
static void AddABS
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeABS
);
}
static void AddADC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeADC
);
}
static void AddADD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeADD
);
}
static void AddBCLR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBCLR
);
}
static void AddBCnd
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBCnd
);
}
static void AddBMCnd
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBMCnd
);
}
static void AddBRK
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBRK
);
}
static void AddBSR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBSR
);
}
static void AddCLRPSW
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeCLRPSW
);
}
static void AddDIV
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDIV
);
}
static void AddFADD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeFADD
);
}
static void AddINT
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeINT
);
}
static void AddITOF
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeITOF
);
}
static void AddJMP
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeJMP
);
}
static void AddMACHI
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMACHI
);
}
static void AddMOV
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMOV
);
}
static void AddMOVU
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMOVU
);
}
static void AddMVFACHI
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVFACHI
);
}
static void AddMVFC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVFC
);
}
static void AddMVTACHI
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVTACHI
);
}
static void AddMVTC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVTC
);
}
static void AddMVTIPL
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVTIPL
);
}
static void AddPOPC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodePOPC
);
}
static void AddPOPM
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodePOPM
);
}
static void AddPUSH
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodePUSH
);
}
static void AddRACW
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRACW
);
}
static void AddRMPA
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRMPA
);
}
static void AddROTL
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeROTL
);
}
static void AddRTE
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRTE
);
}
static void AddRTSD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRTSD
);
}
static void AddSCCnd
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeSCCnd
);
}
static void AddSHAR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeSHAR
);
}
static void AddSTNZ
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeSTNZ
);
}
static void AddTST
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeTST
);
}
static void AddMOVCO
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMOVCO
);
}
static void AddMOVLI
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMOVLI
);
}
static void AddBFMOV
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBFMOV
);
}
static void AddRSTR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeRSTR
);
}
static void AddDABS
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDABS
);
}
static void AddDADD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDADD
);
}
static void AddDCMPcm
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDCMPcm
);
}
static void AddDMOV
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDMOV
);
}
static void AddDPOPM
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeDPOPM
);
}
static void AddFTOD
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeFTOD
);
}
static void AddMVFDC
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVFDC
);
}
static void AddMVFDR
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeMVFDR
);
}
#ifdef COMPAT
static void AddBLK
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeIntelDS
);
}
#endif /* COMPAT */
static Boolean TrueFnc
(void)
{
return True
;
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(201);
/* RXv1 */
AddABS
("ABS", 0x200F);
AddADC
("ADC", 0x0802);
AddADD
("ADD", 0);
AddADD
("AND", 1);
AddBCLR
("BCLR", 0);
AddBCnd
("BEQ", 0);
AddBCnd
("BZ", 0);
AddBCnd
("BNE", 1);
AddBCnd
("BNZ", 1);
AddBCnd
("BGEU", 2);
AddBCnd
("BC", 2);
AddBCnd
("BLTU", 3);
AddBCnd
("BNC", 3);
AddBCnd
("BGTU", 4);
AddBCnd
("BLEU", 5);
AddBCnd
("BPZ", 6);
AddBCnd
("BN", 7);
AddBCnd
("BGE", 8);
AddBCnd
("BLT", 9);
AddBCnd
("BGT", 10);
AddBCnd
("BLE", 11);
AddBCnd
("BO", 12);
AddBCnd
("BNO", 13);
AddBMCnd
("BMEQ", 0);
AddBMCnd
("BMZ", 0);
AddBMCnd
("BMNE", 1);
AddBMCnd
("BMNZ", 1);
AddBMCnd
("BMGEU", 2);
AddBMCnd
("BMC", 2);
AddBMCnd
("BMLTU", 3);
AddBMCnd
("BMNC", 3);
AddBMCnd
("BMGTU", 4);
AddBMCnd
("BMLEU", 5);
AddBMCnd
("BMPZ", 6);
AddBMCnd
("BMN", 7);
AddBMCnd
("BMGE", 8);
AddBMCnd
("BMLT", 9);
AddBMCnd
("BMGT", 10);
AddBMCnd
("BMLE", 11);
AddBMCnd
("BMO", 12);
AddBMCnd
("BMNO", 13);
AddBCLR
("BNOT", 1);
AddBCnd
("BRA", 14);
AddBRK
("BRK", 0x0000);
AddBCLR
("BSET", 2);
AddBSR
("BSR", 0);
AddBCLR
("BTST", 3);
AddCLRPSW
("CLRPSW", 0xB0);
AddADD
("CMP", 2);
AddDIV
("DIV", 0);
AddDIV
("DIVU", 1);
AddDIV
("EMUL", 2);
AddDIV
("EMULU", 3);
AddFADD
("FADD", 0);
AddFADD
("FCMP", 1);
AddFADD
("FDIV", 2);
AddFADD
("FMUL", 3);
AddFADD
("FSUB", 4);
AddFADD
("FTOI", 5);
AddINT
("INT", 0);
AddITOF
("ITOF", 0);
AddJMP
("JMP", 0);
AddJMP
("JSR", 1);
AddMACHI
("MACHI", 0);
AddMACHI
("MACLO", 1);
AddDIV
("MAX", 4);
AddDIV
("MIN", 5);
AddMOV
("MOV", 0);
AddMOVU
("MOVU", 0);
AddADD
("MUL", 3);
AddMACHI
("MULHI", 2);
AddMACHI
("MULLO", 3);
AddMVFACHI
("MVFACHI", 0);
AddMVFACHI
("MVFACMI", 1);
AddMVFC
("MVFC", 0);
AddMVTACHI
("MVTACHI", 0);
AddMVTACHI
("MVTACLO", 1);
AddMVTC
("MVTC", 0);
AddMVTIPL
("MVTIPL", 0);
AddABS
("NEG", 0x1007);
AddBRK
("NOP", 0x0003);
AddABS
("NOT", 0x003B);
AddADD
("OR", 4);
AddJMP
("POP", 2);
AddPOPC
("POPC", 0);
AddPOPM
("POPM", 0);
AddPUSH
("PUSH", 0);
AddPOPC
("PUSHC", 1);
AddPOPM
("PUSHM", 1);
AddRACW
("RACW", 0);
AddMACHI
("REVL", 4);
AddMACHI
("REVW", 5);
AddRMPA
("RMPA", 0x8C);
AddJMP
("ROLC", 3);
AddJMP
("RORC", 4);
AddROTL
("ROTL", 0);
AddROTL
("ROTR", 1);
AddFADD
("ROUND", 6);
AddRTE
("RTE", 0x7F95);
AddRTE
("RTFI", 0x7F94);
AddBRK
("RTS", 0x0002);
AddRTSD
("RTSD", 0);
AddJMP
("SAT", 5);
AddRTE
("SATR", 0x7F93);
AddADC
("SBB", 0x0000);
AddSCCnd
("SCEQ", 0);
AddSCCnd
("SCZ", 0);
AddSCCnd
("SCNE", 1);
AddSCCnd
("SCNZ", 1);
AddSCCnd
("SCGEU", 2);
AddSCCnd
("SCC", 2);
AddSCCnd
("SCLTU", 3);
AddSCCnd
("SCNC", 3);
AddSCCnd
("SCGTU", 4);
AddSCCnd
("SCLEU", 5);
AddSCCnd
("SCPZ", 6);
AddSCCnd
("SCN", 7);
AddSCCnd
("SCGE", 8);
AddSCCnd
("SCLT", 9);
AddSCCnd
("SCGT", 10);
AddSCCnd
("SCLE", 11);
AddSCCnd
("SCO", 12);
AddSCCnd
("SCNO", 13);
AddRTE
("SCMPU", 0x7F83);
AddCLRPSW
("SETPSW", 0xA0);
AddSHAR
("SHAR", 0);
AddSHAR
("SHLL", 1);
AddSHAR
("SHLR", 2);
AddRTE
("SMOVB", 0x7F8B);
AddRTE
("SMOVF", 0x7F8F);
AddRTE
("SMOVU", 0x7F87);
AddRMPA
("SSTR", 0x88);
AddSTNZ
("STNZ", 0);
AddSTNZ
("STZ", 1);
AddADD
("SUB", 5);
AddRMPA
("SUNTIL", 0x80);
AddRMPA
("SWHILE", 0x84);
AddTST
("TST", 0);
AddRTE
("WAIT", 0x7F96);
AddTST
("XCHG", 1);
AddTST
("XOR", 2);
/* RXv2 */
AddFADD
("FSQRT", 7);
AddFADD
("FTOU", 8);
AddITOF
("UTOF", 1);
AddMOVCO
("MOVCO", 0);
AddMOVLI
("MOVLI", 0);
AddMACHI
("EMACA", 6);
AddMACHI
("EMSBA", 7);
AddMACHI
("EMULA", 8);
AddMACHI
("MACLH", 9);
AddMACHI
("MSBHI", 10);
AddMACHI
("MSBLH", 11);
AddMACHI
("MSBLO", 12);
AddMACHI
("MULLH", 13);
AddMVFACHI
("MVFACGU", 2);
AddMVFACHI
("MVFACLO", 3);
AddMVTACHI
("MVTACGU", 2);
AddRACW
("RACL", 1);
AddRACW
("RDACL", 2);
AddRACW
("RDACW", 3);
/* RXv3 */
AddBFMOV
("BFMOV", 0);
AddBFMOV
("BFMOVZ", 1);
AddRSTR
("RSTR", 0);
AddRSTR
("SAVE", 1); SaveIsOccupiedFnc
= TrueFnc
;
AddDABS
("DABS", 0);
AddDADD
("DADD", 0);
AddDCMPcm
("DCMPUN", 0x01);
AddDCMPcm
("DCMPEQ", 0x02);
AddDCMPcm
("DCMPLT", 0x04);
AddDCMPcm
("DCMPLE", 0x06);
AddDADD
("DDIV", 1);
AddDMOV
("DMOV", 0);
AddDADD
("DMUL", 2);
AddDABS
("DNEG", 1);
AddDPOPM
("DPOPM", 0);
AddDPOPM
("DPUSHM", 1);
AddDABS
("DROUND", 2);
AddDABS
("DSQRT", 3);
AddDADD
("DSUB", 3);
AddDABS
("DTOF", 4);
AddDABS
("DTOI", 5);
AddDABS
("DTOU", 6);
AddFTOD
("FTOD", 0);
AddFTOD
("ITOD", 1);
AddMVFDC
("MVFDC", 0);
AddMVFDR
("MVFDR", 0);
AddMVFDC
("MVTDC", 1);
AddFTOD
("UTOD", 2);
/* Pseudo Instructions */
#ifdef COMPAT
AddInstTable
(InstTable
, "ENDIAN", 0, DecodeENDIAN
);
AddBLK
("BLKB", 1);
AddBLK
("BLKW", 2);
AddBLK
("BLKL", 4);
AddBLK
("BLKD", 8);
AddInstTable
(InstTable
, "BYTE", eIntPseudoFlag_AllowInt
| eIntPseudoFlag_AllowString
, DecodeIntelDB
);
AddInstTable
(InstTable
, "WORD", eIntPseudoFlag_AllowInt
, DecodeWORD
);
AddInstTable
(InstTable
, "LWORD", eIntPseudoFlag_AllowInt
, DecodeLWORD
);
AddInstTable
(InstTable
, "FLOAT", eIntPseudoFlag_AllowFloat
, DecodeFLOAT
);
AddInstTable
(InstTable
, "DOUBLE", eIntPseudoFlag_AllowFloat
, DecodeDOUBLE
);
#endif
StrCompAlloc
(&Temp1
, STRINGSIZE
);
StrCompAlloc
(&Temp2
, STRINGSIZE
);
}
static void DeinitFields
(void)
{
StrCompFree
(&Temp2
);
StrCompFree
(&Temp1
);
DestroyInstTable
(InstTable
);
}
/*---------------------------------------------------------------------------*/
static void MakeCode_RX
(void)
{
CodeLen
= 0;
DontPrint
= False
;
if (Memo
("")) return;
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
static Boolean IsDef_RX
(void)
{
return False
;
}
static void SwitchFrom_RX
(void)
{
DeinitFields
();
}
static void SwitchTo_RX
(void *pUser
)
{
const TFamilyDescr
*pDescr
;
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
pDescr
= FindFamilyByName
("RX");
PCSymbol
= "$";
HeaderID
= pDescr
->Id
;
NOPCode
= 0x03;
DivideChars
= ",";
HasAttrs
= True
;
AttrChars
= ".";
ValidSegs
= (1 << SegCode
);
Grans
[SegCode
] = 1;
ListGrans
[SegCode
] = 1;
SegInits
[SegCode
] = 0x0000;
SegLimits
[SegCode
] = (LargeWord
)IntTypeDefs
[UInt32
].
Max;
MakeCode
= MakeCode_RX
;
IsDef
= IsDef_RX
;
SwitchFrom
= SwitchFrom_RX
;
InitFields
();
onoff_supmode_add
();
onoff_bigendian_add
();
pCurrCPUProps
= (const tCPUProps
*)pUser
;
}
static const tCPUProps CPUProps
[] =
{
/* Group InsSet FLT DBL RegB MVTIPL */
{ "RXV1", eRXv1
, True
, False
, 0, True
}, /* Generic RXv1 (Full option) */
{ "RX110", eRXv1
, False
, False
, 0, True
},
{ "RX111", eRXv1
, False
, False
, 0, True
},
{ "RX113", eRXv1
, False
, False
, 0, True
},
{ "RX130", eRXv1
, False
, False
, 0, True
},
{ "RX210", eRXv1
, False
, False
, 0, True
},
{ "RX21A", eRXv1
, False
, False
, 0, True
},
{ "RX220", eRXv1
, False
, False
, 0, True
},
{ "RX610", eRXv1
, True
, False
, 0, False
},
{ "RX621", eRXv1
, True
, False
, 0, True
},
{ "RX62N", eRXv1
, True
, False
, 0, True
},
{ "RX630", eRXv1
, True
, False
, 0, True
},
{ "RX631", eRXv1
, True
, False
, 0, True
},
{ "RXV2", eRXv2
, True
, False
, 0, True
}, /* Generic RXv2 */
{ "RX140", eRXv2
, True
, False
, 0, True
},
{ "RX230", eRXv2
, True
, False
, 0, True
},
{ "RX231", eRXv2
, True
, False
, 0, True
},
{ "RX64M", eRXv2
, True
, False
, 0, True
},
{ "RX651", eRXv2
, True
, False
, 0, True
},
{ "RXV3", eRXv3
, True
, True
, 256, True
}, /* Generic RXv3 (Full option) */
{ "RX660", eRXv3
, True
, False
, 16, True
},
{ "RX671", eRXv3
, True
, True
, 16, True
},
{ "RX72M", eRXv3
, True
, True
, 16, True
},
{ "RX72N", eRXv3
, True
, True
, 16, True
},
{ "" , eRXv1
, False
, False
, 0, False
}
};
void coderx_init
(void)
{
const tCPUProps
*pProp
;
for (pProp
= CPUProps
; pProp
->Name
[0]; pProp
++)
(void)AddCPUUser
(pProp
->Name
, SwitchTo_RX
, (void *)pProp
, NULL
);
AddCopyright
("Renesas RX Generator (C) 2023 Haruo Asano");
}