Merge remote-tracking branch 'origin/GP-3211_ghidorahrex_loongson_proc'

(Closes #5083)
This commit is contained in:
Ryan Kurtz 2023-11-14 12:18:15 -05:00
commit 0f09d6fed3
42 changed files with 18091 additions and 53 deletions

View file

@ -13,14 +13,39 @@ from pcodetest import *
# set default properties first, then update values from the command
# line before they are instantiated.
def test_action(action_class, deprecate=False):
class pcodeTestAction(action_class):
def __call__(self, parser, namespace, values, option_string=None):
c = getattr(namespace, 'command_count', 0)
setattr(namespace, 'command_count', c+1)
if deprecate:
print('Deprecated pcodetest command\n\tuse --%s' % (self.dest))
action_class.__call__(self, parser, namespace, values, option_string)
return pcodeTestAction
exec(compile(open('defaults.py', "rb").read(), 'defaults.py', 'exec'))
parser = argparse.ArgumentParser(description='''Build pcodetests.
One and only one of the following options must be given:
[--pcodetest, --pcodetest-all, --pcodetest-list]''',
[--test, --all, --list]''',
epilog='(*) default properties for pcodetest instances',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
# required alternates
required_group = parser.add_argument_group('Pcodetest Commands')
required_group.add_argument('-t', '--test', dest='test', action=test_action(argparse._StoreAction), help='the pcode test to build')
required_group.add_argument('-a', '--all', dest='all', action=test_action(argparse._StoreTrueAction), help='build all pcode tests')
required_group.add_argument('-l', '--list', dest='list', action=test_action(argparse._StoreTrueAction), help='list available pcode tests')
#Deprecated
required_group.add_argument('--pcodetest', dest='test', action=test_action(argparse._StoreAction, True), help=argparse.SUPPRESS)
required_group.add_argument('--pcodetest-all',dest='all', action=test_action(argparse._StoreTrueAction, True), help=argparse.SUPPRESS)
required_group.add_argument('--pcodetest-list', dest='list', action=test_action(argparse._StoreTrueAction, True), help=argparse.SUPPRESS)
# all-applicable arguments
parser.add_argument('-f', '--force', action='store_true', help='force a build')
@ -29,16 +54,10 @@ parser.add_argument('--toolchain-root', default=PCodeTest.defaults.toolchain_roo
parser.add_argument('--build-root', default=PCodeTest.defaults.build_root, help='temporary directory to hold build files (*)')
parser.add_argument('--gcc-version', default=PCodeTest.defaults.gcc_version, help='default version of gcc (*)')
# required alternates
required_group = parser.add_mutually_exclusive_group(required=True)
required_group.add_argument('--pcodetest', help='the pcode test to build')
required_group.add_argument('--pcodetest-all', action='store_true', help='build all pcode tests')
required_group.add_argument('--pcodetest-list', action='store_true', help='list available pcode tests')
# pcodetest arguments
pcodetest_group = parser.add_argument_group('pcodetest', 'pcodetest options')
pcodetest_group = parser.add_argument_group('Pcodetest Options')
pcodetest_group.add_argument('--no-publish', action='store_true', help='do not publish pcode test binaries to pcode test root')
pcodetest_group.add_argument('--pcodetest-root', default=PCodeTest.defaults.pcodetest_root, help='location to publish pcode tests binaries (*)')
pcodetest_group.add_argument('--pcodetest-src', default=PCodeTest.defaults.pcodetest_src, help='location of pcode test .c and .h source files (*)')
@ -49,6 +68,7 @@ pcodetest_group.add_argument('--add-info', action='store_true', help='add data t
pcodetest_group.add_argument('--build-exe', action='store_true', help='build a guest executable binary (exe)')
pcodetest_group.add_argument('--variants', default=json.dumps(PCodeTest.defaults.variants, sort_keys=True, separators=(',',':')), type=json.loads, help='build the (optimization) variants, encoded as a json dict')
sys.argv.pop(0)
args = parser.parse_args(sys.argv)
@ -73,9 +93,21 @@ exec(compile(open('pcode_defs.py', "rb").read(), 'pcode_defs.py', 'exec'))
cwd = os.getcwd()
if args.pcodetest_list:
if not hasattr(args, 'command_count'):
print('ERROR: One of [--test, --all, --list] must be given\n')
parser.print_help()
exit()
if args.command_count > 1:
print('ERROR: Two many commands given. Only one of [--test, --all, --list] must be given\n')
parser.print_help()
exit()
if args.list:
PCodeTest.print_all()
elif args.pcodetest_all:
elif args.all:
for n,pct in sorted(PCodeTest.list.items(), key=lambda x: x[0].lower()):
if pct.config.build_all:
try: PCodeTestBuild.factory(pct).main()
@ -83,12 +115,13 @@ elif args.pcodetest_all:
print('unhandled exception while building %s' % n)
traceback.print_exc(file=sys.stdout)
os.chdir(cwd)
elif args.pcodetest:
if args.pcodetest in PCodeTest.list:
PCodeTest = PCodeTest.list[args.pcodetest]
elif args.test:
if args.test in PCodeTest.list:
PCodeTest = PCodeTest.list[args.test]
PCodeTestBuild.factory(PCodeTest).main()
else:
print('the pcode test %s is not in the list' % args.pcodetest)
print('the pcode test %s is not in the list' % args.test)
else:
parser.print_help()

View file

@ -1,5 +1,18 @@
#include "pcode_test.h"
#ifdef HAS_DOUBLE
TEST f8_compareLogic_Main()
{
extern f8 f8_compareLogic(f8 lhs, f8 rhs);
ASSERTF8(f8_compareLogic(0x1, 0x1), 21);
ASSERTF8(f8_compareLogic(0x1, 0x2), 21);
ASSERTF8(f8_compareLogic(0x2, 0x1), 22);
ASSERTF8(f8_compareLogic(-0x1, -0x1), 21);
ASSERTF8(f8_compareLogic(-0x1, -0x2), 21);
ASSERTF8(f8_compareLogic(-0x2, -0x1), 24);
}
#endif
/* Comparison operators */
#ifdef HAS_DOUBLE
TEST f8_greaterThan_Main()

View file

@ -16,6 +16,19 @@
#include "pcode_test.h"
#ifdef HAS_DOUBLE
f8 f8_compareLogic(f8 lhs, f8 rhs)
{
if (lhs < 0)
lhs += 2;
if (lhs > 0)
lhs += 4;
if (lhs == 0)
lhs += 8;
if (lhs != rhs)
lhs += 16;
return lhs;
}
/* Comparison operators */
f8 f8_greaterThan(f8 lhs, f8 rhs)
{

View file

@ -13,19 +13,6 @@ TEST f4_compareLogic_Main()
}
#endif
#ifdef HAS_DOUBLE
TEST f8_compareLogic_Main()
{
extern f8 f8_compareLogic(f8 lhs, f8 rhs);
ASSERTF8(f8_compareLogic(0x1, 0x1), 21);
ASSERTF8(f8_compareLogic(0x1, 0x2), 21);
ASSERTF8(f8_compareLogic(0x2, 0x1), 22);
ASSERTF8(f8_compareLogic(-0x1, -0x1), 21);
ASSERTF8(f8_compareLogic(-0x1, -0x2), 21);
ASSERTF8(f8_compareLogic(-0x2, -0x1), 24);
}
#endif
/* Comparison operators */
#ifdef HAS_FLOAT
TEST f4_greaterThan_Main()

View file

@ -29,19 +29,6 @@ f4 f4_compareLogic(f4 lhs, f4 rhs)
return lhs;
}
f8 f8_compareLogic(f8 lhs, f8 rhs)
{
if (lhs < 0)
lhs += 2;
if (lhs > 0)
lhs += 4;
if (lhs == 0)
lhs += 8;
if (lhs != rhs)
lhs += 16;
return lhs;
}
/* Comparison operators */
f4 f4_greaterThan(f4 lhs, f4 rhs)
{

View file

@ -107,6 +107,8 @@ typedef unsigned int u4;
typedef signed int i4;
#ifdef HAS_LONGLONG
typedef long long i8;
#endif
#if defined(HAS_LONGLONG) || defined(HAS__DOUBLE)
typedef unsigned long long u8;
#endif
#ifdef HAS_FLOAT
@ -132,6 +134,8 @@ typedef signed int i4;
#endif
#ifdef HAS_LONGLONG
typedef long long i8;
#endif
#if defined(HAS_LONGLONG) || defined(HAS__DOUBLE)
typedef unsigned long long u8;
#endif
#ifdef HAS_FLOAT
@ -197,10 +201,8 @@ typedef __UINT8_TYPE__ u1;
typedef __UINT16_TYPE__ u2;
typedef __UINT32_TYPE__ u4;
#if defined(__UINT64_TYPE__)
#ifdef HAS_LONGLONG
typedef __UINT64_TYPE__ u8;
#endif
#endif
#ifdef __SIZEOF_FLOAT__
#ifdef HAS_FLOAT

View file

@ -20,19 +20,17 @@
PCodeTest.defaults.toolchain_root = '/local/ToolChains'
PCodeTest.defaults.build_root = '/local/build-pcodetest'
PCodeTest.defaults.gcc_version = '7.3.0'
PCodeTest.defaults.gcc_version = '9.2.0'
PCodeTest.defaults.skip_files = []
PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/'
PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src'
# PCodeTest.defaults that cannot be overridden on the command line
# These are set by processor test definitions in the pcode_defs.py file
PCodeTest.defaults.build_all = 0
PCodeTest.defaults.ccflags = ''
PCodeTest.defaults.has_decimal128 = 0
PCodeTest.defaults.has_decimal32 = 0
PCodeTest.defaults.has_decimal64 = 0
PCodeTest.defaults.has_double = 1
PCodeTest.defaults.has_float = 1

View file

@ -219,6 +219,32 @@ PCodeTest({
'architecture_test': 'PARISC',
})
PCodeTest({
'name': 'Loongarch64',
'build_all': 1,
'build_exe': 0,
'gcc_version': '12.3.0',
'qemu_command': 'qemu-loongarch64',
'target': 'loongson-linux',
'toolchain': '%(name)s/%(target)s', #%(toolchain_dir)s/lib/gcc/loongarch64-linux/%(gcc_version)s
'ccflags': '-march=loongarch64 -mabi=lp64d -L /local/cross/lib/gcc/loongarch64-linux/12.3.0/ -lgcc',
'language_id': 'Loongarch:LE:64:default',
#'has_longlong': 0,
})
PCodeTest({
'name': 'Loongarch64f',
'build_all': 1,
'build_exe': 0,
'gcc_version': '12.3.0',
'qemu_command': 'qemu-loongarch64',
'target': 'loongson-linux',
'toolchain': 'Loongarch64/%(target)s', #%(toolchain_dir)s/lib/gcc/loongarch64-linux/%(gcc_version)s
'ccflags': '-march=loongarch64 -mabi=lp64f -mfpu=32 -L /local/cross/lib/gcc/loongarch64-linux/12.3.0/ -lgcc',
'language_id': 'Loongarch:LE:64:lp64f',
'has_double': 0,
})
# Note that libgcc.a was built for m68020 which has a different function calling convention from pre-68020

View file

@ -400,9 +400,10 @@ class PCodeBuildGCC(PCodeTestBuild):
# can pass this if weak symbols aren't defined
# f += ['-Xlinker', '--unresolved-symbols=ignore-all']
f += self.config.ccflags.split()
f += self.config.add_ccflags.split()
f +=[self.config.format(g) for g in self.config.ccflags.split()]
f += [self.config.format(g) for g in self.config.add_ccflags.split()]
self.log_info('Compiler flags: %s' % f)
return f
def compile(self, input_files, opt_cflag, output_base):

View file

@ -392,7 +392,10 @@ public interface ElfConstants {
public static final short EM_TI_C2000 = 141;
/** The Texas Instruments TMS320C55x DSP family */
public static final short EM_TI_C5500 = 142;
// 143 - 159 reserved
// 143 reserved
/** Texas Instruments Programmable Realtime Unit */
public static final short EM_TI_PRU = 144;
// 145 - 159 reserved
/** STMicroelectronics 64bit VLIW Data Signal Processor */
public static final short EM_MMDSP_PLUS = 160;
/** Cypress M8C microprocessor */
@ -439,9 +442,10 @@ public interface ElfConstants {
public static final short EM_L10M = 180;
/** Intel K10M */
public static final short EM_K10M = 181;
// 182 reserved
// 182 reserved by Intel
/** AARCH64 Architecture */
public static final short EM_AARCH64 = 183;
// 184 reserved by ARM
/** Atmel Corporation 32-bit microprocessor family */
public static final short EM_AVR32 = 185;
/** STMicroeletronics STM8 8-bit microcontroller */
@ -480,7 +484,9 @@ public interface ElfConstants {
public static final short EM_XCORE = 203;
/** Microchip 8-bit PIC(r) family */
public static final short EM_MCHP_PIC = 204;
// 205 - 209 reserved by Intel
/** Intel Graphics Technology */
public static final short EM_INTELGT = 205;
// 206 - 209 reserved by Intel
/** KM211 KM32 32-bit processor */
public static final short EM_KM32 = 210;
/** KM211 KMX32 32-bit processor */
@ -501,15 +507,56 @@ public interface ElfConstants {
public static final short EM_NORC = 218;
/** CSR Kalimba architecture family */
public static final short EM_CSR_KALIMBA = 219;
// 220 - 223 reserved
/** Zilog Z80 */
public static final short EM_Z80 = 220;
/** Controls and Data Services VISIUMcore processor */
public static final short EM_VISIUM = 221;
/** FTDI Chip FT32 high performance 32-bit RISC architecture */
public static final short EM_FT32 = 222;
/** Moxie processor family */
public static final short EM_MOXIE = 223;
/** AMD GPU architecture */
public static final short EM_AMDGPU = 224;
/** RISC-V */
public static final short EM_RISCV = 243;
/** Lanai 32-bit processor */
public static final short EM_LANAI = 244;
/** CEVA Processor Architecture Family */
public static final short EM_CEVA = 245;
/** CEVA X2 Processor Family */
public static final short EM_CEVA_X2 = 246;
/** Linux kernel bpf virtual machine */
public static final short EM_BPF = 247;
/** Graphcore Intelligent Processing Unit */
public static final short EM_GRAPHCORE_IPU = 248;
/** Imagination Technologies */
public static final short EM_IMG1 = 249;
/** Netronome Flow Processor. */
public static final short EM_NFP = 250;
/** NEC Vector Engine */
public static final short EM_VE = 251;
/** C-SKY processor family. */
public static final short EM_CSKY = 252;
/** Synopsys ARCv2.3 64-bit */
public static final short EM_ARC_COMPACT3_64 = 253;
/** MOS Technology MCS 6502 processor */
public static final short EM_MCS6502 = 254;
/** Synopsys ARCv2.3 32-bit */
public static final short EM_ARC_COMPACT3 = 255;
/** Kalray VLIW core of the MPPA processor family */
public static final short EM_KVX = 256;
/** WDC 65816/65C816 */
public static final short EM_65816 = 257;
/** LoongArch*/
public static final short EM_LOONGARCH = 258;
/** ChipON KungFu32 */
public static final short EM_KF32 = 259;
/** Linux kernel bpf virtual machine */
public static final short EM_U16_U8CORE = 260;
/** Tachyum */
public static final short EM_TACHYUM = 261;
/** NXP 56800EF Digital Signal Controller (DSC) */
public static final short EM_56800EF = 262;
/** used by NetBSD/avr32 - AVR 32-bit */
public static final short EM_AVR32_unofficial = 0x18ad;

View file

@ -0,0 +1,27 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
apply plugin: 'eclipse'
eclipse.project.name = 'Processors Loongarch'
dependencies {
api project(':Base')
}

View file

@ -0,0 +1,26 @@
##VERSION: 2.0
Module.manifest||GHIDRA||||END|
data/languages/ilp32d.cspec||GHIDRA||||END|
data/languages/ilp32f.cspec||GHIDRA||||END|
data/languages/lasx.sinc||GHIDRA||||END|
data/languages/lbt.sinc||GHIDRA||||END|
data/languages/loongarch.ldefs||GHIDRA||||END|
data/languages/loongarch.opinion||GHIDRA||||END|
data/languages/loongarch32.pspec||GHIDRA||||END|
data/languages/loongarch32_f32.slaspec||GHIDRA||||END|
data/languages/loongarch32_f64.slaspec||GHIDRA||||END|
data/languages/loongarch32_instructions.sinc||GHIDRA||||END|
data/languages/loongarch64.pspec||GHIDRA||||END|
data/languages/loongarch64_f32.slaspec||GHIDRA||||END|
data/languages/loongarch64_f64.slaspec||GHIDRA||||END|
data/languages/loongarch64_instructions.sinc||GHIDRA||||END|
data/languages/loongarch_double.sinc||GHIDRA||||END|
data/languages/loongarch_float.sinc||GHIDRA||||END|
data/languages/loongarch_main.sinc||GHIDRA||||END|
data/languages/lp64d.cspec||GHIDRA||||END|
data/languages/lp64f.cspec||GHIDRA||||END|
data/languages/lsx.sinc||GHIDRA||||END|
data/languages/lvz.sinc||GHIDRA||||END|
data/manuals/loongarch.idx||GHIDRA||||END|
data/patterns/loongarch_patterns.xml||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|

View file

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<integer_size value="4" />
<long_size value="4" />
<pointer_size value="4"/>
<float_size value="4" />
<double_size value="8" />
<long_double_size value="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
<entry size="16" alignment="16" />
</size_alignment_map>
</data_organization>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/>
<global>
<range space="ram"/>
<range space="register" first="0x2000" last="0x2fff"/>
</global>
<returnaddress>
<register name="ra"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa7"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a1"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a2"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a5"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a6"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a7"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a2" piece2="a3"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a4" piece2="a5"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a6" piece2="a7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
</output>
<killedbycall>
<register name="t0"/>
<register name="t1"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
<register name="t8"/>
<register name="ft0"/>
<register name="ft1"/>
<register name="ft2"/>
<register name="ft3"/>
<register name="ft4"/>
<register name="ft5"/>
<register name="ft6"/>
<register name="ft7"/>
<register name="ft8"/>
<register name="ft9"/>
<register name="ft10"/>
<register name="ft11"/>
<register name="ft12"/>
<register name="ft13"/>
<register name="ft14"/>
<register name="ft15"/>
</killedbycall>
<unaffected>
<register name="s0"/>
<register name="s1"/>
<register name="s2"/>
<register name="s3"/>
<register name="s4"/>
<register name="s5"/>
<register name="s6"/>
<register name="s7"/>
<register name="s8"/>
<register name="sp"/>
<register name="fp"/>
<register name="fs0"/>
<register name="fs1"/>
<register name="fs2"/>
<register name="fs3"/>
<register name="fs4"/>
<register name="fs5"/>
<register name="fs6"/>
<register name="fs7"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>

View file

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<integer_size value="4" />
<long_size value="4" />
<pointer_size value="4"/>
<float_size value="4" />
<double_size value="8" />
<long_double_size value="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
<entry size="16" alignment="16" />
</size_alignment_map>
</data_organization>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/>
<global>
<range space="ram"/>
<range space="register" first="0x2000" last="0x2fff"/>
</global>
<returnaddress>
<register name="ra"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa7"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a1"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a2"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a5"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a6"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a7"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a2" piece2="a3"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a4" piece2="a5"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a6" piece2="a7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="a0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
</output>
<killedbycall>
<register name="t0"/>
<register name="t1"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
<register name="t8"/>
<register name="ft0"/>
<register name="ft1"/>
<register name="ft2"/>
<register name="ft3"/>
<register name="ft4"/>
<register name="ft5"/>
<register name="ft6"/>
<register name="ft7"/>
<register name="ft8"/>
<register name="ft9"/>
<register name="ft10"/>
<register name="ft11"/>
<register name="ft12"/>
<register name="ft13"/>
<register name="ft14"/>
<register name="ft15"/>
</killedbycall>
<unaffected>
<register name="s0"/>
<register name="s1"/>
<register name="s2"/>
<register name="s3"/>
<register name="s4"/>
<register name="s5"/>
<register name="s6"/>
<register name="s7"/>
<register name="s8"/>
<register name="sp"/>
<register name="fp"/>
<register name="fs0"/>
<register name="fs1"/>
<register name="fs2"/>
<register name="fs3"/>
<register name="fs4"/>
<register name="fs5"/>
<register name="fs6"/>
<register name="fs7"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="Loongarch"
endian="little"
size="32"
variant="ilp32f"
version="1.0"
slafile="loongarch32_f32.sla"
processorspec="loongarch32.pspec"
manualindexfile="../manuals/loongarch.idx"
id="Loongarch:LE:32:ilp32f">
<description>Loongson 3 32-bit with 32-bit FP</description>
<compiler name="gnu" spec="ilp32f.cspec" id="default"/>
<external_name tool="gnu" name="Loongarch32"/>
</language>
<language processor="Loongarch"
endian="little"
size="32"
variant="ilp32d"
version="1.0"
slafile="loongarch32_f64.sla"
processorspec="loongarch32.pspec"
manualindexfile="../manuals/loongarch.idx"
id="Loongarch:LE:32:ilp32d">
<description>Loongson 3 32-bit with 64-bit FP</description>
<compiler name="default" spec="ilp32d.cspec" id="default"/>
<external_name tool="gnu" name="Loongarch32"/>
</language>
<language processor="Loongarch"
endian="little"
size="64"
variant="lp64d"
version="1.0"
slafile="loongarch64_f64.sla"
processorspec="loongarch64.pspec"
manualindexfile="../manuals/loongarch.idx"
id="Loongarch:LE:64:lp64d">
<description>Loongson 3 64-bit with 64-bit FP</description>
<compiler name="default" spec="lp64d.cspec" id="default"/>
<external_name tool="gnu" name="Loongarch64"/>
</language>
<language processor="Loongarch"
endian="little"
size="64"
variant="lp64f"
version="1.0"
slafile="loongarch64_f32.sla"
processorspec="loongarch64.pspec"
manualindexfile="../manuals/loongarch.idx"
id="Loongarch:LE:64:lp64f">
<description>Loongson 3 64-bit with 64-bit FP</description>
<compiler name="default" spec="lp64f.cspec" id="default"/>
<external_name tool="gnu" name="Loongarch64"/>
</language>
</language_definitions>

View file

@ -0,0 +1,23 @@
<opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="258" processor="Loongarch" size="64" variant="lp64d"
secondary= "0b .... .... .... .... .... .... .... .001"/>
<constraint primary="258" processor="Loongarch" size="64" variant="lp64f"
secondary= "0b .... .... .... .... .... .... .... .010"/>
<constraint primary="258" processor="Loongarch" size="64" variant="lp64d"
secondary= "0b .... .... .... .... .... .... .... .011"/>
<constraint primary="258" processor="Loongarch" size="32" variant="ilp32f"
secondary= "0b .... .... .... .... .... .... .... .001"/>
<constraint primary="258" processor="Loongarch" size="32" variant="ilp32f"
secondary= "0b .... .... .... .... .... .... .... .010"/>
<constraint primary="258" processor="Loongarch" size="32" variant="ilp32d"
secondary= "0b .... .... .... .... .... .... .... .011"/>
</constraint>
</opinions>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="pc"/>
<register_data>
<register name="contextreg" hidden="true"/>
</register_data>
</processor_spec>

View file

@ -0,0 +1,13 @@
@define REGSIZE 4
@define FREGSIZE 4
@define ADDRSIZE 4
@include "loongarch_main.sinc"
@include "loongarch32_instructions.sinc"
@include "loongarch_float.sinc"
@include "loongarch_double.sinc"
@include "lasx.sinc"
@include "lbt.sinc"
@include "lsx.sinc"
@include "lvz.sinc"

View file

@ -0,0 +1,12 @@
@define REGSIZE 4
@define FREGSIZE 8
@define ADDRSIZE 4
@include "loongarch_main.sinc"
@include "loongarch32_instructions.sinc"
@include "loongarch_float.sinc"
@include "loongarch_double.sinc"
#@include "lasx.sinc"
#@include "lbt.sinc"
#@include "lsx.sinc"
#@include "lvz.sinc"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="pc"/>
<register_data>
<register name="contextreg" hidden="true"/>
</register_data>
</processor_spec>

View file

@ -0,0 +1,19 @@
@define LA64 ""
@define REGSIZE 8
@define FREGSIZE 4
@define ADDRSIZE 8
@include "loongarch_main.sinc"
@include "loongarch32_instructions.sinc"
@include "loongarch64_instructions.sinc"
@include "loongarch_float.sinc"
@include "loongarch_double.sinc"
@include "lasx.sinc"
@include "lbt.sinc"
@include "lsx.sinc"
@include "lvz.sinc"

View file

@ -0,0 +1,15 @@
@define LA64 ""
@define REGSIZE 8
@define FREGSIZE 8
@define ADDRSIZE 8
@include "loongarch_main.sinc"
@include "loongarch32_instructions.sinc"
@include "loongarch64_instructions.sinc"
@include "loongarch_float.sinc"
@include "loongarch_double.sinc"
@include "lasx.sinc"
@include "lbt.sinc"
@include "lsx.sinc"
@include "lvz.sinc"

View file

@ -0,0 +1,760 @@
###################
# Base Instructions
###################
#la-base-64.txt add.d mask=0x00108000 [@qemu]
#0x00108000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:add.d RD, RJsrc, RKsrc is op15_31=0x21 & RD & RJsrc & RKsrc {
RD = RJsrc + RKsrc;
}
#la-base-64.txt addi.d mask=0x02c00000 [@qemu]
#0x02c00000 0xffc00000 r0:5,r5:5,s10:12 ['reg0_5_s0', 'reg5_5_s0', 'simm10_12_s0']
:addi.d RD, RJsrc,simm10_12 is op22_31=0xb & RD & RJsrc & simm10_12 {
RD = RJsrc + simm10_12;
}
#la-base-64.txt addu16i.d mask=0x10000000 [@qemu]
#0x10000000 0xfc000000 r0:5,r5:5,s10:16 ['reg0_5_s0', 'reg5_5_s0', 'simm10_16_s0']
:addu16i.d RD, RJsrc, addu16_imm is op26_31=0x4 & RD & RJsrc & addu16_imm {
RD = RJsrc + addu16_imm;
}
#la-bitops-64.txt sladd.d mask=0x002c0000 [@orig_name=alsl.d, @orig_fmt=DJKUa2pp1]
#0x002c0000 0xfffe0000 r0:5,r5:5,r10:5,u15:2+1 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0', 'imm15_2+1_s0']
:alsl.d RD, RJsrc, RKsrc, alsl_shift is op17_31=0x16 & RD & RJsrc & RKsrc & alsl_shift {
RD = (RJsrc << alsl_shift) + RKsrc;
}
#la-bitops-64.txt sladd.wu mask=0x00060000 [@orig_name=alsl.wu, @orig_fmt=DJKUa2pp1]
#0x00060000 0xfffe0000 r0:5,r5:5,r10:5,u15:2+1 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0', 'imm15_2+1_s0']
:alsl.wu RD, RJ32src, RK32src, alsl_shift is op17_31=0x3 & RD & RJ32src & RK32src & alsl_shift {
local result:4 = (RJ32src << alsl_shift) + RK32src;
RD = zext(result);
}
#la-mul-64.txt div.d mask=0x00220000 [@qemu]
#0x00220000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:div.d RD, RJsrc, RKsrc is op15_31=0x44 & RD & RJsrc & RKsrc {
RD = RJsrc s/ RKsrc;
}
#la-mul-64.txt div.du mask=0x00230000 [@qemu]
#0x00230000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:div.du RD, RJsrc, RKsrc is op15_31=0x46 & RD & RJsrc & RKsrc {
RD = RJsrc / RKsrc;
}
#la-mul-64.txt mod.d mask=0x00228000 [@qemu]
#0x00228000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mod.d RD, RJsrc, RKsrc is op15_31=0x45 & RD & RJsrc & RKsrc {
RD = RJsrc s% RKsrc;
}
#la-mul-64.txt mod.du mask=0x00238000 [@qemu]
#0x00238000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mod.du RD, RJsrc, RKsrc is op15_31=0x47 & RD & RJsrc & RKsrc {
RD = RJsrc % RKsrc;
}
#la-mul-64.txt mul.d mask=0x001d8000 [@qemu]
#0x001d8000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mul.d RD, RJsrc, RKsrc is op15_31=0x3b & RD & RJsrc & RKsrc {
tmp1:16 = sext( RJsrc );
tmp2:16 = sext( RKsrc );
prod:16 = tmp1 * tmp2;
RD = prod:8;
}
#la-mul-64.txt mulh.d mask=0x001e0000 [@qemu]
#0x001e0000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mulh.d RD, RJsrc, RKsrc is op15_31=0x3c & RD & RJsrc & RKsrc {
tmp1:16 = sext( RJsrc );
tmp2:16 = sext( RKsrc );
prod:16 = tmp1 * tmp2;
prod = prod >> 64;
RD = prod:8;
}
#la-mul-64.txt mulh.du mask=0x001e8000 [@qemu]
#0x001e8000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mulh.du RD, RJsrc, RKsrc is op15_31=0x3d & RD & RJsrc & RKsrc {
tmp1:16 = zext( RJsrc );
tmp2:16 = zext( RKsrc );
prod:16 = tmp1 * tmp2;
prod = prod >> 64;
RD = prod:8;
}
#la-mul-64.txt mulw.d.w mask=0x001f0000
#0x001f0000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mulw.d.w RD, RJ32src, RK32src is op15_31=0x3e & RD & RJ32src & RK32src {
tmp1:8 = sext( RJ32src );
tmp2:8 = sext( RK32src );
prod:8 = tmp1 * tmp2;
RD = prod;
}
#la-mul-64.txt mulw.d.wu mask=0x001f8000
#0x001f8000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:mulw.d.wu RD, RJ32src, RK32src is op15_31=0x3f & RD & RJ32src & RK32src {
tmp1:8 = zext( RJ32src );
tmp2:8 = zext( RK32src );
prod:8 = tmp1 * tmp2;
RD = prod;
}
#la-base-64.txt rdtime.d mask=0x00006800
#0x00006800 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:rdtime.d RD, RJ is op10_31=0x1a & RD & RJ {
local tmp:1 = 2;
RD = rdtime.counter(tmp);
RJ = rdtime.counterid(tmp);
}
#la-base-64.txt rotr.d mask=0x001b8000 [@qemu]
#0x001b8000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:rotr.d RD, RJsrc, RKsrc is op15_31=0x37 & RD & RJsrc & RKsrc {
local shift:1 = RKsrc(0) & 0x3f;
local tmp1:8 = RJsrc s>> shift;
local tmp2:8 = RJsrc << (64 - shift);
RD = tmp1 + tmp2;
}
#la-base-64.txt rotri.d mask=0x004d0000 [@qemu]
#0x004d0000 0xffff0000 r0:5,r5:5,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm10_6_s0']
:rotri.d RD, RJsrc, imm10_6 is op16_31=0x4d & RD & RJsrc & imm10_6 {
local shift:1 = imm10_6 & 0x3f;
local tmp1:8 = RJsrc s>> shift;
local tmp2:8 = RJsrc << (64 - shift);
RD = tmp1 + tmp2;
}
#la-base-64.txt sll.d mask=0x00188000 [@qemu]
#0x00188000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:sll.d RD, RJsrc, RKsrc is op15_31=0x31 & RD & RJsrc & RKsrc {
local shift:1 = RKsrc(0) & 0x3f;
RD = RJsrc << shift;
}
#la-base-64.txt slli.d mask=0x00410000 [@qemu]
#0x00410000 0xffff0000 r0:5,r5:5,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm10_6_s0']
:slli.d RD, RJsrc, imm10_6 is op16_31=0x41 & RD & RJsrc & imm10_6 {
local shift:1 = imm10_6 & 0x1f;
RD = RJsrc << shift;
}
#la-base-64.txt sra.d mask=0x00198000 [@qemu]
#0x00198000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:sra.d RD, RJsrc, RKsrc is op15_31=0x33 & RD & RJsrc & RKsrc {
local shift:1 = RKsrc(0) & 0x3f;
RD = RJsrc s>> shift;
}
#la-base-64.txt srai.d mask=0x00490000 [@qemu]
#0x00490000 0xffff0000 r0:5,r5:5,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm10_6_s0']
:srai.d RD, RJsrc, imm10_6 is op16_31=0x49 & RD & RJsrc & imm10_6 {
local shift:1 = imm10_6 & 0x1f;
RD = RJsrc s>> shift;
}
#la-base-64.txt srl.d mask=0x00190000 [@qemu]
#0x00190000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:srl.d RD, RJsrc, RKsrc is op15_31=0x32 & RD & RJsrc & RKsrc {
local shift:1 = RKsrc(0) & 0x3f;
RD = RJsrc >> shift;
}
#la-base-64.txt srli.d mask=0x00450000 [@qemu]
#0x00450000 0xffff0000 r0:5,r5:5,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm10_6_s0']
:srli.d RD, RJsrc, imm10_6 is op16_31=0x45 & RD & RJsrc & imm10_6 {
local shift:1 = imm10_6 & 0x1f;
RD = RJsrc >> shift;
}
#la-base-64.txt sub.d mask=0x00118000 [@qemu]
#0x00118000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:sub.d RD, RJsrc, RKsrc is op15_31=0x23 & RD & RJsrc & RKsrc {
RD = RJsrc - RKsrc;
}
##########################
# Load/Store Instructions
##########################
#la-base-64.txt cu52i.d mask=0x03000000 [@orig_name=lu52i.d, @qemu]
#0x03000000 0xffc00000 r0:5,r5:5,s10:12 ['reg0_5_s0', 'reg5_5_s0', 'simm10_12_s0']
:lu52i.d RD, RJsrc, simm52i is op22_31=0xc & RD & RJsrc & simm52i {
RD = simm52i + (RJsrc & 0xfffffffffffff);
}
#la-base-64.txt cu32i.d mask=0x16000000 [@orig_name=lu32i.d, @qemu]
#0x16000000 0xfe000000 r0:5,s5:20 ['reg0_5_s0', 'simm5_20_s0']
:lu32i.d RD, simm32i is op25_31=0xb & RD & RD32 & simm32i {
RD = simm32i + zext(RD32);
}
#la-base-64.txt ldox4.d mask=0x26000000 [@orig_name=ldptr.d, @orig_fmt=DJSk14ps2]
#0x26000000 0xff000000 r0:5,r5:5,so10:14<<2 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_14_s0']
:ldptr.d RD, ldstptr_addr is op24_31=0x26 & RD & ldstptr_addr {
RD = *[ram]:8 ldstptr_addr;
}
#la-base-64.txt stox4.d mask=0x27000000 [@orig_name=stptr.d, @orig_fmt=DJSk14ps2]
#0x27000000 0xff000000 r0:5,r5:5,so10:14<<2 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_14_s0']
:stptr.d RDsrc, ldstptr_addr is op24_31=0x27 & RDsrc & ldstptr_addr {
*[ram]:8 ldstptr_addr = RDsrc;
}
#la-base-64.txt ld.d mask=0x28c00000 [@qemu]
#0x28c00000 0xffc00000 r0:5,r5:5,so10:12 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:ld.d RD, ldst_addr is op22_31=0xa3 & RD & ldst_addr {
RD = *[ram]:8 ldst_addr;
}
#la-base-64.txt st.d mask=0x29c00000 [@qemu]
#0x29c00000 0xffc00000 r0:5,r5:5,so10:12 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:st.d RDsrc, ldst_addr is op22_31=0xa7 & RDsrc & ldst_addr {
*[ram]:8 ldst_addr = RDsrc;
}
#la-base-64.txt ld.wu mask=0x2a800000 [@qemu]
#0x2a800000 0xffc00000 r0:5,r5:5,so10:12 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:ld.wu RD, ldst_addr is op22_31=0xaa & RD & ldst_addr {
RD = zext(*[ram]:4 ldst_addr);
}
#la-base-64.txt ldx.d mask=0x380c0000 [@qemu]
#0x380c0000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:ldx.d RD, ldstx_addr is op15_31=0x7018 & RD & ldstx_addr {
RD = *[ram]:8 ldstx_addr;
}
#la-base-64.txt stx.d mask=0x381c0000 [@qemu]
#0x381c0000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:stx.d RDsrc, ldstx_addr is op15_31=0x7038 & RDsrc & ldstx_addr {
*[ram]:8 ldstx_addr = RDsrc;
}
#la-base-64.txt ldx.wu mask=0x38280000 [@qemu]
#0x38280000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:ldx.wu RD, ldstx_addr is op15_31=0x7050 & RD & ldstx_addr {
RD = zext(*[ram]:4 ldstx_addr);
}
######################
# Atomic Instructions
######################
#la-atomics-64.txt ll.d mask=0x22000000 [@orig_fmt=DJSk14ps2]
#0x22000000 0xff000000 r0:5,r5:5,so10:14<<2 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_14_s0']
:ll.d RD, ldstptr_addr is op24_31=0x22 & RD & ldstptr_addr {
RD = *[ram]:8 ldstptr_addr;
}
#la-atomics-64.txt sc.d mask=0x23000000 [@orig_fmt=DJSk14ps2]
#0x23000000 0xff000000 r0:5,r5:5,so10:14<<2 ['reg0_5_s0', 'reg5_5_s0', 'soffs10_14_s0']
:sc.d RD, ldstptr_addr is op24_31=0x23 & RD & ldstptr_addr {
*[ram]:8 ldstptr_addr = RD;
}
#la-atomics-64.txt amswap.d mask=0x38608000 [@orig_fmt=DKJ]
#0x38608000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amswap.d RD, RJsrc, RKsrc is op15_31=0x70c1 & RD & RJsrc & RKsrc {
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = RKsrc;
}
#la-atomics-64.txt amadd.d mask=0x38618000 [@orig_fmt=DKJ]
#0x38618000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amadd.d RD, RJsrc, RKsrc is op15_31=0x70c3 & RD & RJsrc & RKsrc {
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc + val);
}
#la-atomics-64.txt amand.d mask=0x38628000 [@orig_fmt=DKJ]
#0x38628000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amand.d RD, RJsrc, RKsrc is op15_31=0x70c5 & RD & RJsrc & RKsrc {
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc & val);
}
#la-atomics-64.txt amor.d mask=0x38638000 [@orig_fmt=DKJ]
#0x38638000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amor.d RD, RJsrc, RKsrc is op15_31=0x70c7 & RD & RJsrc & RKsrc {
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc | val);
}
#la-atomics-64.txt amxor.d mask=0x38648000 [@orig_fmt=DKJ]
#0x38648000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amxor.d RD, RJsrc, RKsrc is op15_31=0x70c9 & RD & RJsrc & RKsrc {
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc ^ val);
}
#la-atomics-64.txt ammax.d mask=0x38658000 [@orig_fmt=DKJ]
#0x38658000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax.d RD, RJsrc, RKsrc is op15_31=0x70cb & RD & RJsrc & RKsrc {
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 s>= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin.d mask=0x38668000 [@orig_fmt=DKJ]
#0x38668000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin.d RD, RJsrc, RKsrc is op15_31=0x70cd & RD & RJsrc & RKsrc {
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 s<= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammax.wu mask=0x38670000 [@orig_fmt=DKJ]
#0x38670000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax.wu RD, RJsrc, RK32src is op15_31=0x70ce & RD & RJsrc & RK32src {
local val1:4 = *[ram]:4 RJsrc;
local val2:4 = RK32src;
local test = (val1 >= val2);
RD = sext(val1);
*[ram]:4 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammax.du mask=0x38678000 [@orig_fmt=DKJ]
#0x38678000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax.du RD, RJsrc, RKsrc is op15_31=0x70cf & RD & RJsrc & RKsrc {
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 >= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin.wu mask=0x38680000 [@orig_fmt=DKJ]
#0x38680000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin.wu RD, RJsrc, RK32src is op15_31=0x70d0 & RD & RJsrc & RK32src {
local val1:4 = *[ram]:4 RJsrc;
local val2:4 = RK32src;
local test = (val1 <= val2);
RD = sext(val1);
*[ram]:4 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin.du mask=0x38688000 [@orig_fmt=DKJ]
#0x38688000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin.du RD, RJsrc, RKsrc is op15_31=0x70d1 & RD & RJsrc & RKsrc {
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 <= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt amswap_db.d mask=0x38698000 [@orig_fmt=DKJ]
#0x38698000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amswap_db.d RD, RJsrc, RKsrc is op15_31=0x70d3 & RD & RJsrc & RKsrc {
dbar(0:1);
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = RKsrc;
}
#la-atomics-64.txt amadd_db.d mask=0x386a8000 [@orig_fmt=DKJ]
#0x386a8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amadd_db.d RD, RJsrc, RKsrc is op15_31=0x70d5 & RD & RJsrc & RKsrc {
dbar(0:1);
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc + val);
}
#la-atomics-64.txt amand_db.d mask=0x386b8000 [@orig_fmt=DKJ]
#0x386b8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amand_db.d RD, RJsrc, RKsrc is op15_31=0x70d7 & RD & RJsrc & RKsrc {
dbar(0:1);
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc & val);
}
#la-atomics-64.txt amor_db.d mask=0x386c8000 [@orig_fmt=DKJ]
#0x386c8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amor_db.d RD, RJsrc, RKsrc is op15_31=0x70d9 & RD & RJsrc & RKsrc {
dbar(0:1);
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc | val);
}
#la-atomics-64.txt amxor_db.d mask=0x386d8000 [@orig_fmt=DKJ]
#0x386d8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:amxor_db.d RD, RJsrc, RKsrc is op15_31=0x70db & RD & RJsrc & RKsrc {
dbar(0:1);
local val:8 = *[ram]:8 RJsrc;
RD = val;
*[ram]:8 RJsrc = (RKsrc ^ val);
}
#la-atomics-64.txt ammax_db.d mask=0x386e8000 [@orig_fmt=DKJ]
#0x386e8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax_db.d RD, RJsrc, RKsrc is op15_31=0x70dd & RD & RJsrc & RKsrc {
dbar(0:1);
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 s>= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin_db.d mask=0x386f8000 [@orig_fmt=DKJ]
#0x386f8000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin_db.d RD, RJsrc, RKsrc is op15_31=0x70df & RD & RJsrc & RKsrc {
dbar(0:1);
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 s<= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammax_db.wu mask=0x38700000 [@orig_fmt=DKJ]
#0x38700000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax_db.wu RD, RJsrc, RK32src is op15_31=0x70e0 & RD & RJsrc & RK32src {
dbar(0:1);
local val1:4 = *[ram]:4 RJsrc;
local val2:4 = RK32src;
local test = (val1 >= val2);
RD = sext(val1);
*[ram]:4 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammax_db.du mask=0x38708000 [@orig_fmt=DKJ]
#0x38708000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammax_db.du RD, RJsrc, RKsrc is op15_31=0x70e1 & RD & RJsrc & RKsrc {
dbar(0:1);
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 >= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin_db.wu mask=0x38710000 [@orig_fmt=DKJ]
#0x38710000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin_db.wu RD, RJsrc, RK32src is op15_31=0x70e2 & RD & RJsrc & RK32src {
dbar(0:1);
local val1:4 = *[ram]:4 RJsrc;
local val2:4 = RK32src;
local test = (val1 <= val2);
RD = sext(val1);
*[ram]:4 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
#la-atomics-64.txt ammin_db.du mask=0x38718000 [@orig_fmt=DKJ]
#0x38718000 0xffff8000 r0:5,r10:5,r5:5 ['reg0_5_s0', 'reg10_5_s0', 'reg5_5_s0']
:ammin_db.du RD, RJsrc, RKsrc is op15_31=0x70e3 & RD & RJsrc & RKsrc {
dbar(0:1);
local val1:8 = *[ram]:8 RJsrc;
local val2:8 = RKsrc;
local test = (val1 <= val2);
RD = val1;
*[ram]:8 RJsrc = (zext(test) * val1) + (zext(!test) * val2);
}
################################
# Bit-manipulation Instructions
################################
#la-bitops-64.txt clo.d mask=0x00002000
#0x00002000 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:clo.d RD, RJsrc is op10_31=0x8 & RD & RJsrc {
RD = lzcount( ~RJsrc );
}
#la-bitops-64.txt clz.d mask=0x00002400 [@qemu]
#0x00002400 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:clz.d RD, RJsrc is op10_31=0x9 & RD & RJsrc {
RD = lzcount( RJsrc );
}
#la-bitops-64.txt cto.d mask=0x00002800
#0x00002800 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:cto.d RD, RJsrc is op10_31=0xa & RD & RJsrc {
local tmp:8 = 0;
tzcount64(~RJsrc, tmp);
RD = tmp;
}
#la-bitops-64.txt ctz.d mask=0x00002c00 [@qemu]
#0x00002c00 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:ctz.d RD, RJsrc is op10_31=0xb & RD & RJsrc {
local tmp:8 = 0;
tzcount64(RJsrc, tmp);
RD = tmp;
}
#la-bitops-64.txt revb.4h mask=0x00003400
#0x00003400 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:revb.4h RD, RJsrc is op10_31=0xd & RD & RJsrc {
tmp0:8 = (zext(RJsrc[0,8]) << 8) + zext(RJsrc[8,8]);
tmp1:8 = (zext(RJsrc[16,8]) << 8) + zext(RJsrc[24,8]);
tmp2:8 = (zext(RJsrc[32,8]) << 8) + zext(RJsrc[40,8]);
tmp3:8 = (zext(RJsrc[48,8]) << 8) + zext(RJsrc[56,8]);
RD = (tmp3 << 48) + (tmp2 << 32) + (tmp1 << 16) + tmp0;
}
#la-bitops-64.txt revb.2w mask=0x00003800 [@qemu]
#0x00003800 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:revb.2w RD, RJsrc is op10_31=0xe & RD & RJsrc {
tmp0:8 = (zext(RJsrc[0,8]) << 24) + (zext(RJsrc[8,8]) << 16) + (zext(RJsrc[16,8]) << 8) + zext(RJsrc[24,8]);
tmp1:8 = (zext(RJsrc[32,8]) << 24) + (zext(RJsrc[40,8]) << 16) + (zext(RJsrc[48,8]) << 8) + zext(RJsrc[56,8]);
RD = (tmp1 << 32) + tmp0;
}
#la-bitops-64.txt revb.d mask=0x00003c00 [@qemu]
#0x00003c00 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:revb.d RD, RJsrc is op10_31=0xf & RD & RJsrc {
tmp0:8 = zext(RJsrc[0,8]);
tmp1:8 = zext(RJsrc[8,8]);
tmp2:8 = zext(RJsrc[16,8]);
tmp3:8 = zext(RJsrc[24,8]);
tmp4:8 = zext(RJsrc[32,8]);
tmp5:8 = zext(RJsrc[40,8]);
tmp6:8 = zext(RJsrc[48,8]);
tmp7:8 = zext(RJsrc[56,8]);
RD = (tmp0 << 56) + (tmp1 << 48) + (tmp2 << 40) + (tmp3 << 32) + (tmp4 << 24) + (tmp5 << 16) + (tmp6 << 8) + tmp7;
}
#la-bitops-64.txt revh.2w mask=0x00004000
#0x00004000 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:revh.2w RD, RJsrc is op10_31=0x10 & RD & RJsrc {
tmp0:8 = (zext(RJsrc[0,16]) << 16) + zext(RJsrc[16,16]);
tmp1:8 = (zext(RJsrc[32,16]) << 8) + zext(RJsrc[48,16]);
RD = (tmp1 << 32) + tmp0;
}
#la-bitops-64.txt revh.d mask=0x00004400
#0x00004400 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:revh.d RD, RJsrc is op10_31=0x11 & RD & RJsrc {
tmp0:8 = zext(RJsrc[0,16]);
tmp1:8 = zext(RJsrc[16,16]);
tmp2:8 = zext(RJsrc[32,16]);
tmp3:8 = zext(RJsrc[48,16]);
RD = (tmp3 << 48) + (tmp2 << 32) + (tmp1 << 16) + tmp0;
}
#la-bitops-64.txt revbit.8b mask=0x00004c00 [@orig_name=bitrev.8b]
#0x00004c00 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:bitrev.8b RD, RJsrc is op10_31=0x13 & RD & RJsrc {
local v:8 = 0;
byterev64(RJsrc, v);
RD = v;
}
#la-bitops-64.txt revbit.d mask=0x00005400 [@orig_name=bitrev.d]
#0x00005400 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:bitrev.d RD, RJsrc is op10_31=0x15 & RD & RJsrc {
local v:8 = 0;
bitrev64(RJsrc, v);
RD = v;
}
define pcodeop bytepick.d;
#la-bitops-64.txt catpick.d mask=0x000c0000 [@orig_name=bytepick.d]
#0x000c0000 0xfffc0000 r0:5,r5:5,r10:5,u15:3 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0', 'imm15_3_s0']
:bytepick.d RD, RJsrc, RKsrc, imm15_3 is op18_31=0x3 & RD & RJsrc & RKsrc & imm15_3 {
local bitstop:1 = 8 * (8 - imm15_3);
local mask:8 = (1 << bitstop) - 1;
local tmp_hi:8 = RKsrc & ~mask;
local tmp_lo:8 = (RJsrc & (mask << (64-bitstop)) >> (64-bitstop));
RD = tmp_hi + tmp_lo;
}
define pcodeop crc.w.d.w;
#la-bitops-64.txt crc.w.d.w mask=0x00258000
#0x00258000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:crc.w.d.w RD, RJsrc, RKsrc is op15_31=0x4b & RD & RJsrc & RKsrc {
RD = crc_ieee802.3(RKsrc, RJsrc, 64:1, 0xedb88320:4);
}
define pcodeop crcc.w.d.w;
#la-bitops-64.txt crcc.w.d.w mask=0x00278000
#0x00278000 0xffff8000 r0:5,r5:5,r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:crcc.w.d.w RD, RJsrc, RKsrc is op15_31=0x4f & RD & RJsrc & RKsrc {
RD = crc_castagnoli(RKsrc, RJsrc, 64:1, 0x82f63b78:4);
}
#la-bitops-64.txt bstrins.d mask=0x00800000 [@orig_fmt=DJUm6Uk6, @qemu]
#0x00800000 0xffc00000 r0:5,r5:5,u16:6,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm16_6_s0', 'imm10_6_s0']
:bstrins.d RD, RJsrc, imm16_6, imm10_6 is op22_31=0x2 & RD & RJsrc & imm10_6 & imm16_6 {
local msb:1 = imm16_6;
local lsb:1 = imm10_6;
local len:1 = msb + 1 - lsb;
local mask:8 = (1 << len) - 1;
local repl:8 = (RJsrc & (mask << lsb)) >> lsb;
RD = (RD & (~mask)) | repl;
}
#la-bitops-64.txt bstrpick.d mask=0x00c00000 [@orig_fmt=DJUm6Uk6, @qemu]
#0x00c00000 0xffc00000 r0:5,r5:5,u16:6,u10:6 ['reg0_5_s0', 'reg5_5_s0', 'imm16_6_s0', 'imm10_6_s0']
:bstrpick.d RD, RJsrc, imm16_6, imm10_6 is op22_31=0x3 & RD & RJsrc & imm10_6 & imm16_6 {
local msb:1 = imm16_6;
local lsb:1 = imm10_6;
local len:1 = msb + 1 - lsb;
local mask:8 = (1 << len) - 1;
local repl:8 = (RJsrc & (mask << lsb)) >> lsb;
RD = repl;
}
###############################
# Bounds-checking Instructions
###############################
#la-bound-64.txt ldgt.d mask=0x38798000
#0x38798000 0xffff8000 r0:5, r5:5, r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:ldgt.d RD, RJsrc, RKsrc is op15_31=0x70f3 & RD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
RD = sext(*[ram]:8 vaddr);
}
#la-bound-64.txt ldle.d mask=0x387b8000
#0x387b8000 0xffff8000 r0:5, r5:5, r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:ldle.d RD, RJsrc, RKsrc is op15_31=0x70f7 & RD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
RD = sext(*[ram]:1 vaddr);
}
#la-bound-64.txt stgt.d mask=0x387d8000
#0x387d8000 0xffff8000 r0:5, r5:5, r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:stgt.d RDsrc, RJsrc, RKsrc is op15_31=0x70fb & RDsrc & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:8 vaddr = RDsrc:8;
}
#la-bound-64.txt stle.d mask=0x387f8000
#0x387f8000 0xffff8000 r0:5, r5:5, r10:5 ['reg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:stle.d RDsrc, RJsrc, RKsrc is op15_31=0x70ff & RDsrc & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:8 vaddr = RDsrc:8;
}
#########################
# PRIVILEGED INSTRUCTIONS
#########################
#la-privileged-64.txt iocsrrd.d mask=0x06480c00
#0x06480c00 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:iocsrrd.d RD, RJsrc is op10_31=0x19203 & RD & RJsrc {
RD = *[iocsr]:8 RJsrc;
}
#la-privileged-64.txt iocsrwr.d mask=0x06481c00
#0x06481c00 0xfffffc00 r0:5,r5:5 ['reg0_5_s0', 'reg5_5_s0']
:iocsrwr.d RDsrc, RJsrc is op10_31=0x19207 & RDsrc & RJsrc {
*[iocsr]:8 RJsrc = RDsrc;
}

View file

@ -0,0 +1,388 @@
#la-fp-d.txt fadd.d mask=0x01010000
#0x01010000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fadd.d drD, drJ, drK is op15_31=0x202 & drD & drJ & drK {
drD = drJ f+ drK;
}
#la-fp-d.txt fsub.d mask=0x01030000
#0x01030000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fsub.d drD, drJ, drK is op15_31=0x206 & drD & drJ & drK {
drD = drJ f- drK;
}
#la-fp-d.txt fmul.d mask=0x01050000
#0x01050000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmul.d drD, drJ, drK is op15_31=0x20a & drD & drJ & drK {
drD = drJ f* drK;
}
#la-fp-d.txt fdiv.d mask=0x01070000
#0x01070000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fdiv.d drD, drJ, drK is op15_31=0x20e & drD & drJ & drK {
drD = drJ f/ drK;
}
#la-fp-d.txt fmax.d mask=0x01090000
#0x01090000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmax.d drD, drJ, drK is op15_31=0x212 & drD & drJ & drK {
local jval = drJ;
local kval = drK;
local test = jval f>= kval;
drD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-d.txt fmin.d mask=0x010b0000
#0x010b0000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmin.d drD, drJ, drK is op15_31=0x216 & drD & drJ & drK {
local jval = drJ;
local kval = drK;
local test = jval f<= kval;
drD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-d.txt fmaxa.d mask=0x010d0000
#0x010d0000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmaxa.d drD, drJ, drK is op15_31=0x21a & drD & drJ & drK {
local jval = drJ;
local kval = drK;
local test = (abs(jval) f>= abs(kval));
drD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-d.txt fmina.d mask=0x010f0000
#0x010f0000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmina.d drD, drJ, drK is op15_31=0x21e & drD & drJ & drK {
local jval = drJ;
local kval = drK;
local test = (abs(jval) f<= abs(kval));
drD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-d.txt fscaleb.d mask=0x01110000
#0x01110000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fscaleb.d drD, drJ, drK is op15_31=0x222 & drD & drJ & drK {
drD = f_scaleb(drJ, drK);
}
#la-fp-d.txt fcopysign.d mask=0x01130000
#0x01130000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fcopysign.d drD, drJ, drK is op15_31=0x226 & drD & drJ & drK {
local kval = drK & 0x8000000000000000;
local jval = drJ & 0x7fffffffffffffff;
drD = kval | jval ;
}
#la-fp-d.txt fabs.d mask=0x01140800
#0x01140800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fabs.d drD, drJ is op10_31=0x4502 & drD & drJ {
drD = abs(drJ);
}
#la-fp-d.txt fneg.d mask=0x01141800
#0x01141800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fneg.d drD, drJ is op10_31=0x4506 & drD & drJ {
drD = f- drJ;
}
#la-fp-d.txt flogb.d mask=0x01142800
#0x01142800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:flogb.d drD, drJ is op10_31=0x450a & drD & drJ {
drD = f_logb(drJ);
}
#la-fp-d.txt fclass.d mask=0x01143800
#0x01143800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fclass.d drD, drJ is op10_31=0x450e & drD & drJ {
drD = f_class(drD, drJ);
}
#la-fp-d.txt fsqrt.d mask=0x01144800
#0x01144800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fsqrt.d drD, drJ is op10_31=0x4512 & drD & drJ {
drD = sqrt(drJ);
}
#la-fp-d.txt frecip.d mask=0x01145800
#0x01145800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frecip.d drD, drJ is op10_31=0x4516 & drD & drJ {
local one:4 = 1;
drD = int2float(one) f/ drJ;
}
#la-fp-d.txt frsqrt.d mask=0x01146800
#0x01146800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frsqrt.d drD, drJ is op10_31=0x451a & drD & drJ {
local one:4 = 1;
drD = int2float(one) f/ sqrt(drJ);
}
#la-fp-d.txt fmov.d mask=0x01149800
#0x01149800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fmov.d drD, drJ is op10_31=0x4526 & drD & drJ {
drD = drJ;
}
@ifdef LA64
#la-fp-d.txt movgr2fr.d mask=0x0114a800
#0x0114a800 0xfffffc00 f0:5, r5:5 ['freg0_5_s0', 'reg5_5_s0']
:movgr2fr.d drD, RJsrc is op10_31=0x452a & drD & RJsrc {
drD = RJsrc;
}
#la-fp-d.txt movfr2gr.d mask=0x0114b800
#0x0114b800 0xfffffc00 r0:5, f5:5 ['reg0_5_s0', 'freg5_5_s0']
:movfr2gr.d RD, drJ is op10_31=0x452e & RD & drJ {
RD = drJ;
}
@endif
#la-fp-d.txt fcvt.s.d mask=0x01191800
#0x01191800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fcvt.s.d drD, drJ is op10_31=0x4646 & drD & drJ & frD {
frD = float2float(drJ);
}
#la-fp-d.txt fcvt.d.s mask=0x01192400
#0x01192400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fcvt.d.s drD, drJ is op10_31=0x4649 & drD & drJ & frJ {
drD = float2float(frJ);
}
#la-fp-d.txt ftintrm.w.d mask=0x011a0800
#0x011a0800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrm.w.d drD, drJ is op10_31=0x4682 & drD & drJ {
local val:4 = trunc(drJ);
drD = zext(val);
}
#la-fp-d.txt ftintrm.l.d mask=0x011a2800
#0x011a2800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrm.l.d drD, drJ is op10_31=0x468a & drD & drJ {
drD = trunc(drJ);
}
#la-fp-d.txt ftintrp.w.d mask=0x011a4800
#0x011a4800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrp.w.d drD, drJ is op10_31=0x4692 & drD & drJ {
local val:4 = trunc(drJ);
drD = zext(val);
}
#la-fp-d.txt ftintrp.l.d mask=0x011a6800
#0x011a6800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrp.l.d drD, drJ is op10_31=0x469a & drD & drJ {
drD = trunc(drJ);
}
#la-fp-d.txt ftintrz.w.d mask=0x011a8800
#0x011a8800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrz.w.d drD, drJ is op10_31=0x46a2 & drD & drJ {
local val:4 = trunc(drJ);
drD = zext(val);
}
#la-fp-d.txt ftintrz.l.d mask=0x011aa800
#0x011aa800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrz.l.d drD, drJ is op10_31=0x46aa & drD & drJ {
drD = trunc(drJ);
}
#la-fp-d.txt ftintrne.w.d mask=0x011ac800
#0x011ac800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrne.w.d drD, drJ is op10_31=0x46b2 & drD & drJ {
local val:4 = round_even(drJ);
drD = zext(val);
}
#la-fp-d.txt ftintrne.l.d mask=0x011ae800
#0x011ae800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrne.l.d drD, drJ is op10_31=0x46ba & drD & drJ {
drD = round_even(drJ);
}
#la-fp-d.txt ftint.w.d mask=0x011b0800
#0x011b0800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftint.w.d drD, drJ is op10_31=0x46c2 & drD & drJ {
local val:4 = trunc(drJ);
drD = zext(val);
}
#la-fp-d.txt ftint.l.d mask=0x011b2800
#0x011b2800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftint.l.d drD, drJ is op10_31=0x46ca & drD & drJ {
drD = trunc(drJ);
}
#la-fp-d.txt ffint.d.w mask=0x011d2000
#0x011d2000 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ffint.d.w drD, drJ is op10_31=0x4748 & drD & drJ & frJ {
drD = int2float(frJ);
}
#la-fp-d.txt ffint.d.l mask=0x011d2800
#0x011d2800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ffint.d.l drD, drJ is op10_31=0x474a & drD & drJ {
drD = int2float(drJ);
}
#la-fp-d.txt frint.d mask=0x011e4800
#0x011e4800 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frint.d drD, drJ is op10_31=0x4792 & drD & drJ {
local val:8 = trunc(drJ);
drD = int2float(val);
}
#la-fp-d.txt fmadd.d mask=0x08200000
#0x08200000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fmadd.d drD, drJ, drK, drA is op20_31=0x82 & drD & drJ & drK & drA {
drD = (drJ f* drK) f+ drA;
}
#la-fp-d.txt fmsub.d mask=0x08600000
#0x08600000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fmsub.d drD, drJ, drK, drA is op20_31=0x86 & drD & drJ & drK & drA {
drD = (drJ f* drK) f- drA;
}
#la-fp-d.txt fnmadd.d mask=0x08a00000
#0x08a00000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fnmadd.d drD, drJ, drK, drA is op20_31=0x8a & drD & drJ & drK & drA {
drD = f- ((drJ f* drK) f+ drA);
}
#la-fp-d.txt fnmsub.d mask=0x08e00000
#0x08e00000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fnmsub.d drD, drJ, drK, drA is op20_31=0x8e & drD & drJ & drK & drA {
drD = f- ((drJ f* drK) f- drA);
}
dSNaN: "c" is ccf_s = 0 { }
dSNaN: "s" is ccf_s = 1 { }
dcond: dSNaN^"af" is ccf=0x0 & dSNaN { DCMPR = 0; }
dcond: dSNaN^"lt" is ccf=0x1 & dSNaN { DCMPR = DCMP1 f< DCMP2; }
dcond: dSNaN^"eq" is ccf=0x2 & dSNaN { DCMPR = DCMP1 f== DCMP2; }
dcond: dSNaN^"le" is ccf=0x3 & dSNaN { DCMPR = DCMP1 f<= DCMP2; }
dcond: dSNaN^"un" is ccf=0x4 & dSNaN { DCMPR = nan(DCMP1) || nan(DCMP2); }
dcond: dSNaN^"ult" is ccf=0x5 & dSNaN { DCMPR = (nan(DCMP1) || nan(DCMP2)) || (DCMP1 f< DCMP2); }
dcond: dSNaN^"ueq" is ccf=0x6 & dSNaN { DCMPR = (nan(DCMP1) || nan(DCMP2)) || (DCMP1 f== DCMP2); }
dcond: dSNaN^"ule" is ccf=0x7 & dSNaN { DCMPR = (nan(DCMP1) || nan(DCMP2)) || (DCMP1 f<= DCMP2); }
dcond: dSNaN^"ne" is ccf=0x8 & dSNaN { DCMPR = DCMP1 f!= DCMP2; }
dcond: dSNaN^"or" is ccf=0xa & dSNaN { DCMPR = !(nan(DCMP1) || nan(DCMP2)); }
dcond: dSNaN^"une" is ccf=0xc & dSNaN { DCMPR = (nan(DCMP1) || nan(DCMP2)) || (DCMP1 f!= DCMP2); }
#la-fp-d.txt fcmp.caf.d mask=0x0c200000
#0x0c200000 0xffff8018 c0:3, f5:5, f10:5 ['fcc0_3_s0', 'freg5_5_s0', 'freg10_5_s0']
:fcmp.^dcond^".d" fccD, drJ, drK is op20_31=0xc2 & dcond & op3_4 = 0 & fccD & drJ & drK {
DCMP1 = drJ;
DCMP2 = drK;
build dcond;
fccD = DCMPR;
}
#la-fp-d.txt fld.d mask=0x2b800000
#0x2b800000 0xffc00000 f0:5, r5:5, so10:12 ['freg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:fld.d drD, ldst_addr is op22_31=0xae & drD & ldst_addr {
drD = sext(*[ram]:8 ldst_addr);
}
#la-fp-d.txt fst.d mask=0x2bc00000
#0x2bc00000 0xffc00000 f0:5, r5:5, so10:12 ['freg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:fst.d drD, ldst_addr is op22_31=0xaf & drD & ldst_addr {
*[ram]:8 ldst_addr = drD;
}
#la-fp-d.txt fldx.d mask=0x38340000
#0x38340000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldx.d drD, ldstx_addr is op15_31=0x7068 & drD & ldstx_addr {
drD = *[ram]:8 ldstx_addr;
}
#la-fp-d.txt fstx.d mask=0x383c0000
#0x383c0000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstx.d drD, ldstx_addr is op15_31=0x7078 & drD & ldstx_addr {
*[ram]:8 ldstx_addr = drD;
}
#la-bound-fp-d.txt fldgt.d mask=0x38748000
#0x38748000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldgt.d drD, RJsrc, RKsrc is op15_31=0x70e9 & drD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
drD = sext(*[ram]:8 vaddr);
}
#la-bound-fp-d.txt fldle.d mask=0x38758000
#0x38758000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldle.d drD, RJsrc, RKsrc is op15_31=0x70eb & drD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
drD = sext(*[ram]:8 vaddr);
}
define pcodeop fstgt.d;
#la-bound-fp-d.txt fstgt.d mask=0x38768000
#0x38768000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstgt.d drD, RJsrc, RKsrc is op15_31=0x70ed & drD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:8 vaddr = drD;
}
define pcodeop fstle.d;
#la-bound-fp-d.txt fstle.d mask=0x38778000
#0x38778000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstle.d drD, RJsrc, RKsrc is op15_31=0x70ef & drD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:8 vaddr = drD;
}

View file

@ -0,0 +1,488 @@
####
# General Floating-Point Instructions
####
#la-fp.txt fcsrwr mask=0x0114c000 [@orig_name=movgr2fcsr, @orig_fmt=DJ]
#0x0114c000 0xfffffc1c fc0:2,r5:5 ['fcreg0_2_s0', 'reg5_5_s0']
:movgr2fcsr fcsr, RJ32 is op10_31=0x4530 & RJ32 & RJ32src & fcsr & imm0_5=0 {
fcsr = RJ32src;
}
:movgr2fcsr fcsr^".enables", RJ32 is op10_31=0x4530 & RJ32 & RJ32src & fcsr & imm0_5=1 {
local mask:4 = 0x1f;
fcsr = (fcsr & ~mask) + (RJ32src & mask);
}
:movgr2fcsr fcsr^".flags_cause", RJ32 is op10_31=0x4530 & RJ32 & RJ32src & fcsr & imm0_5=2 {
local mask:4 = 0x1f1f0000;
fcsr = (fcsr & ~mask) + (RJ32src & mask);
}
:movgr2fcsr fcsr^".rm", RJ32 is op10_31=0x4530 & RJ32 & RJ32src & fcsr & imm0_5=3 {
local mask:4 = 0x300;
fcsr = (fcsr & ~mask) + (RJ32src & mask);
}
define pcodeop uncertain_fcsr;
# per the manual: if the fcsr does not exist, the result is uncertain
:movgr2fcsr fcsr, RJ32 is op10_31=0x4530 & RJ32 & RJ32src & fcsr & imm0_5 {
uncertain_fcsr(imm0_5:1);
fcsr = RJ32src;
}
#la-fp.txt fcsrrd mask=0x0114c800 [@orig_name=movfcsr2gr, @orig_fmt=DJ]
#0x0114c800 0xffffff80 r0:5,fc5:2 ['reg0_5_s0', 'fcreg5_2_s0']
:movfcsr2gr RD, fcsr is op10_31=0x4532 & RD & fcsr & imm5_5=0 {
RD = sext(fcsr);
}
:movfcsr2gr RD, fcsr is op10_31=0x4532 & RD & fcsr & imm5_5=1 {
local mask:4 = 0x1f;
RD = sext(fcsr & mask);
}
:movfcsr2gr RD, fcsr is op10_31=0x4532 & RD & fcsr & imm5_5=2 {
local mask:4 = 0x1f1f0000;
RD = sext(fcsr & mask);
}
:movfcsr2gr RD, fcsr is op10_31=0x4532 & RD & fcsr & imm5_5=3 {
local mask:4 = 0x300;
RD = sext(fcsr & mask);
}
# per the manual: if the fcsr does not exist, the result is uncertain
:movfcsr2gr RD, fcsr is op10_31=0x4532 & RD & fcsr & imm5_5 {
uncertain_fcsr(imm5_5:1);
RD = sext(fcsr);
}
#la-fp.txt movfr2fcc mask=0x0114d000 [@orig_name=movfr2cf]
#0x0114d000 0xfffffc18 c0:3,f5:5 ['fcc0_3_s0', 'freg5_5_s0']
:movfr2cf fccD, FRJ is op11_31=0x229a & fccD & FRJ {
fccD = FRJ[0,1];
}
#la-fp.txt movfcc2fr mask=0x0114d400 [@orig_name=movcf2fr]
#0x0114d400 0xffffff00 f0:5,c5:3 ['freg0_5_s0', 'fcc5_3_s0']
:movcf2fr FRD, fccJ is op10_31=0x4535 & FRD & fccJ {
FRD[0,1] = fccJ[0,1];
}
#la-fp.txt movgr2fcc mask=0x0114d800 [@orig_name=movgr2cf]
#0x0114d800 0xfffffc18 c0:3,r5:5 ['fcc0_3_s0', 'reg5_5_s0']
:movgr2cf fccD, RJsrc is op10_31=0x4536 & fccD & RJsrc {
fccD = RJsrc[0,1];
}
#la-fp.txt movfcc2gr mask=0x0114dc00 [@orig_name=movcf2gr]
#0x0114dc00 0xffffff00 r0:5,c5:3 ['reg0_5_s0', 'fcc5_3_s0']
:movcf2gr RD, fccJ is op10_31=0x4537 & RD & fccJ {
RD[0,1] = fccJ[0,1];
}
#la-fp.txt fsel mask=0x0d000000
#0x0d000000 0xfffc0000 f0:5,f5:5,f10:5,c15:3 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'fcc15_3_s0']
:fsel FRD, FRJ, FRK, fccA is op20_31=0xd0 & FRD & FRJ & FRK & fccA {
local test:1 = (fccA == 0);
FRD = (zext(!test) * FRK) + (zext(test) * FRJ);
}
#la-fp.txt bceqz mask=0x48000000 [@orig_fmt=CjSd5k16ps2]
#0x48000000 0xfc000300 c5:3,sb0:5|10:16<<2 ['fcc5_3_s0', 'sbranch0_0_s2']
:bceqz fccJ, Rel21 is op26_31=0x12 & fccJ & op8_9=0 & Rel21 {
if(fccJ == 0) goto Rel21;
}
#la-fp.txt bcnez mask=0x48000100 [@orig_fmt=CjSd5k16ps2]
#0x48000100 0xfc000300 c5:3,sb0:5|10:16<<2 ['fcc5_3_s0', 'sbranch0_0_s2']
:bcnez fccJ, Rel21 is op26_31=0x12 & fccJ & op8_9=1 & Rel21 {
if(fccJ != 0) goto Rel21;
}
#####################################
# Floating-Point Single Instructions
#####################################
#la-fp-s.txt fadd.s mask=0x01008000
#0x01008000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fadd.s frD, frJ, frK is op15_31=0x201 & frD & frJ & frK {
frD = frJ f+ frK;
}
#la-fp-s.txt fsub.s mask=0x01028000
#0x01028000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fsub.s frD, frJ, frK is op15_31=0x205 & frD & frJ & frK {
frD = frJ f- frK;
}
#la-fp-s.txt fmul.s mask=0x01048000
#0x01048000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmul.s frD, frJ, frK is op15_31=0x209 & frD & frJ & frK {
frD = frJ f* frK;
}
#la-fp-s.txt fdiv.s mask=0x01068000
#0x01068000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fdiv.s frD, frJ, frK is op15_31=0x20d & frD & frJ & frK {
frD = frJ f/ frK;
}
#la-fp-s.txt fmadd.s mask=0x08100000
#0x08100000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fmadd.s frD, frJ, frK, frA is op20_31=0x81 & frD & frJ & frK & frA {
frD = (frJ f* frK) f+ frA;
}
#la-fp-s.txt fmsub.s mask=0x08500000
#0x08500000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fmsub.s frD, frJ, frK, frA is op20_31=0x85 & frD & frJ & frK & frA {
frD = (frJ f* frK) f- frA;
}
#la-fp-s.txt fnmadd.s mask=0x08900000
#0x08900000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fnmadd.s frD, frJ, frK, frA is op20_31=0x89 & frD & frJ & frK & frA {
frD = f- ((frJ f* frK) f+ frA);
}
#la-fp-s.txt fnmsub.s mask=0x08d00000
#0x08d00000 0xfff00000 f0:5, f5:5, f10:5, f15:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0', 'freg15_5_s0']
:fnmsub.s frD, frJ, frK, frA is op20_31=0x8d & frD & frJ & frK & frA {
frD = f- ((frJ f* frK) f- frA);
}
#la-fp-s.txt fmax.s mask=0x01088000
#0x01088000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmax.s frD, frJ, frK is op15_31=0x211 & frD & frJ & frK {
local jval = frJ;
local kval = frK;
local test = (jval f>= kval);
frD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-s.txt fmin.s mask=0x010a8000
#0x010a8000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmin.s frD, frJ, frK is op15_31=0x215 & frD & frJ & frK {
local jval = frJ;
local kval = frK;
local test = (jval f<= kval);
frD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-s.txt fmaxa.s mask=0x010c8000
#0x010c8000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmaxa.s frD, frJ, frK is op15_31=0x219 & frD & frJ & frK {
local jval = frJ;
local kval = frK;
local test = (abs(jval) f>= abs(kval));
frD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-s.txt fmina.s mask=0x010e8000
#0x010e8000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fmina.s frD, frJ, frK is op15_31=0x21d & frD & frJ & frK {
local jval = frJ;
local kval = frK;
local test = (abs(jval) f<= abs(kval));
frD = (zext(test) * jval) + (zext(!test) * kval);
}
#la-fp-s.txt fabs.s mask=0x01140400
#0x01140400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fabs.s frD, frJ is op10_31=0x4501 & frD & frJ {
frD = abs(frJ);
}
#la-fp-s.txt fneg.s mask=0x01141400
#0x01141400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fneg.s frD, frJ is op10_31=0x4505 & frD & frJ {
frD = f- frJ;
}
#la-fp-s.txt fsqrt.s mask=0x01144400
#0x01144400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fsqrt.s frD, frJ is op10_31=0x4511 & frD & frJ {
frD = sqrt(frJ);
}
#la-fp-s.txt frecip.s mask=0x01145400
#0x01145400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frecip.s frD, frJ is op10_31=0x4515 & frD & frJ {
local one:4 = 1;
frD = int2float(one) f/ frJ;
}
#la-fp-s.txt frsqrt.s mask=0x01146400
#0x01146400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frsqrt.s frD, frJ is op10_31=0x4519 & frD & frJ {
local one:4 = 1;
frD = int2float(one) f/ sqrt(frJ);
}
#la-fp-s.txt fscaleb.s mask=0x01108000
#0x01108000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fscaleb.s frD, frJ, frK is op15_31=0x221 & frD & frJ & frK {
frD = f_scaleb(frJ, frK);
}
#la-fp-s.txt flogb.s mask=0x01142400
#0x01142400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:flogb.s frD, frJ is op10_31=0x4509 & frD & frJ {
frD = f_logb(frJ);
}
#la-fp-s.txt fcopysign.s mask=0x01128000
#0x01128000 0xffff8000 f0:5, f5:5, f10:5 ['freg0_5_s0', 'freg5_5_s0', 'freg10_5_s0']
:fcopysign.s frD, frJ, frK is op15_31=0x225 & frD & frJ & frK {
local kval = frK & 0x80000000;
local jval = frJ & 0x7fffffff;
frD = kval | jval ;
}
#la-fp-s.txt fclass.s mask=0x01143400
#0x01143400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fclass.s frD, frJ is op10_31=0x450d & frD & frJ {
frD = f_class(frJ);
}
#la-fp-s.txt fmov.s mask=0x01149400
#0x01149400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:fmov.s frD, frJ is op10_31=0x4525 & frD & frJ {
frD = frJ;
}
#la-fp-s.txt movgr2fr.w mask=0x0114a400
#0x0114a400 0xfffffc00 f0:5,r5:5 ['freg0_5_s0', 'reg5_5_s0']
:movgr2fr.w frD, RJ32src is op10_31=0x4529 & frD & RJ32src {
frD = RJ32src;
}
#la-fp-s.txt movgr2frh.w mask=0x0114ac00
#0x0114ac00 0xfffffc00 f0:5,r5:5 ['freg0_5_s0', 'reg5_5_s0']
:movgr2frh.w drD, RJ32src is op10_31=0x452b & drD & RJ32src {
drD = (zext(RJ32src) << 32) | (drD & 0xffffffff);
}
#la-fp-s.txt movfr2gr.s mask=0x0114b400
#0x0114b400 0xfffffc00 r0:5, f5:5 ['reg0_5_s0', 'freg5_5_s0']
:movfr2gr.s RD, frJ is op10_31=0x452d & RD & frJ {
RD = sext(frJ);
}
#la-fp-s.txt movfrh2gr.s mask=0x0114bc00
#0x0114bc00 0xfffffc00 r0:5, f5:5 ['reg0_5_s0', 'freg5_5_s0']
:movfrh2gr.s RD, drJ is op10_31=0x452f & RD & drJ {
RD = sext(drJ[32,32]);
}
#la-fp-s.txt ftintrm.w.s mask=0x011a0400
#0x011a0400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrm.w.s frD, frJ is op10_31=0x4681 & frD & frJ {
frD = trunc(frJ);
}
#la-fp-s.txt ftintrm.l.s mask=0x011a2400
#0x011a2400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrm.l.s frD, frJ is op10_31=0x4689 & frD & frJ {
local val:8 = trunc(frJ);
frD = val(0);
}
#la-fp-s.txt ftintrp.w.s mask=0x011a4400
#0x011a4400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrp.w.s frD, frJ is op10_31=0x4691 & frD & frJ {
frD = trunc(frJ);
}
#la-fp-s.txt ftintrp.l.s mask=0x011a6400
#0x011a6400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrp.l.s frD, frJ is op10_31=0x4699 & frD & frJ {
local val:8 = trunc(frJ);
frD = val(0);
}
#la-fp-s.txt ftintrz.w.s mask=0x011a8400
#0x011a8400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrz.w.s frD, frJ is op10_31=0x46a1 & frD & frJ {
frD = trunc(frJ);
}
#la-fp-s.txt ftintrz.l.s mask=0x011aa400
#0x011aa400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrz.l.s frD, frJ is op10_31=0x46a9 & frD & frJ {
local val:8 = trunc(frJ);
frD = val(0);
}
#la-fp-s.txt ftintrne.w.s mask=0x011ac400
#0x011ac400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrne.w.s frD, frJ is op10_31=0x46b1 & frD & frJ {
frD = round_even(frJ);
}
#la-fp-s.txt ftintrne.l.s mask=0x011ae400
#0x011ae400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftintrne.l.s frD, frJ is op10_31=0x46b9 & frD & frJ {
local val:8 = round_even(frJ);
frD = val(0);
}
#la-fp-s.txt ftint.w.s mask=0x011b0400
#0x011b0400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftint.w.s frD, frJ is op10_31=0x46c1 & frD & frJ {
frD = trunc(frJ);
}
#la-fp-s.txt ftint.l.s mask=0x011b2400
#0x011b2400 0xfffffc00 f0:5, f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ftint.l.s frD, frJ is op10_31=0x46c9 & frD & frJ {
local val:8 = trunc(frJ);
frD = val(0);
}
#la-fp-s.txt ffint.s.w mask=0x011d1000
#0x011d1000 0xfffffc00 f0:5,f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ffint.s.w frD,frJ is op10_31=0x4744 & frD & frJ {
frD =int2float(frJ);
}
#la-fp-s.txt ffint.s.l mask=0x011d1800
#0x011d1800 0xfffffc00 f0:5,f5:5 ['freg0_5_s0', 'freg5_5_s0']
:ffint.s.l frD, drD is op10_31=0x4746 & frD & drD {
frD = int2float(drD);
}
#la-fp-s.txt frint.s mask=0x011e4400
#0x011e4400 0xfffffc00 f0:5,f5:5 ['freg0_5_s0', 'freg5_5_s0']
:frint.s frD,frJ is op10_31=0x4791 & frD & frJ {
local val:4 = trunc(frJ);
frD = int2float(val);
}
#la-fp-s.txt fld.s mask=0x2b000000
#0x2b000000 0xffc00000 f0:5,r5:5,so10:12 ['freg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:fld.s frD, ldst_addr is op22_31=0xac & frD & ldst_addr {
frD = *[ram]:4 ldst_addr;
}
#la-fp-s.txt fst.s mask=0x2b400000
#0x2b400000 0xffc00000 f0:5,r5:5,so10:12 ['freg0_5_s0', 'reg5_5_s0', 'soffs10_12_s0']
:fst.s frD, ldst_addr is op22_31=0xad & frD & ldst_addr {
*[ram]:4 ldst_addr = frD:4;
}
#la-fp-s.txt fldx.s mask=0x38300000
#0x38300000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldx.s frD, ldstx_addr is op15_31=0x7060 & frD & ldstx_addr {
frD = *[ram]:4 ldstx_addr;
}
#la-fp-s.txt fstx.s mask=0x38380000
#0x38380000 0xffff8000 f0:5,r5:5,r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstx.s frD, ldstx_addr is op15_31=0x7070 & frD & ldstx_addr {
*[ram]:4 ldstx_addr = frD;
}
SNaN: "c" is ccf_s = 0 { }
SNaN: "s" is ccf_s = 1 { }
fcond: SNaN^"af" is ccf=0x0 & SNaN { FCMPR = 0; }
fcond: SNaN^"lt" is ccf=0x1 & SNaN { FCMPR = FCMP1 f< FCMP2; }
fcond: SNaN^"eq" is ccf=0x2 & SNaN { FCMPR = FCMP1 f== FCMP2; }
fcond: SNaN^"le" is ccf=0x3 & SNaN { FCMPR = FCMP1 f<= FCMP2; }
fcond: SNaN^"un" is ccf=0x4 & SNaN { FCMPR = nan(FCMP1) || nan(FCMP2); }
fcond: SNaN^"ult" is ccf=0x5 & SNaN { FCMPR = (nan(FCMP1) || nan(FCMP2)) || (FCMP1 f< FCMP2); }
fcond: SNaN^"ueq" is ccf=0x6 & SNaN { FCMPR = (nan(FCMP1) || nan(FCMP2)) || (FCMP1 f== FCMP2); }
fcond: SNaN^"ule" is ccf=0x7 & SNaN { FCMPR = (nan(FCMP1) || nan(FCMP2)) || (FCMP1 f<= FCMP2); }
fcond: SNaN^"ne" is ccf=0x8 & SNaN { FCMPR = FCMP1 f!= FCMP2; }
fcond: SNaN^"or" is ccf=0xa & SNaN { FCMPR = !(nan(FCMP1) || nan(FCMP2)); }
fcond: SNaN^"une" is ccf=0xc & SNaN { FCMPR = (nan(FCMP1) || nan(FCMP2)) || (FCMP1 f!= FCMP2); }
#la-fp-s.txt fcmp.caf.s mask=0x0c100000
#0x0c100000 0xffff8018 c0:3, f5:5, f10:5 ['fcc0_3_s0', 'freg5_5_s0', 'freg10_5_s0']
:fcmp.^fcond^".s" fccD, frJ, frK is op20_31=0xc1 & fcond & op3_4 = 0 & fccD & frJ & frK {
FCMP1 = frJ;
FCMP2 = frK;
build fcond;
fccD = FCMPR;
}
#la-bound-fp-s.txt fldgt.s mask=0x38740000
#0x38740000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldgt.s frD, RJsrc, RKsrc is op15_31=0x70e8 & frD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
frD = sext(*[ram]:4 vaddr);
}
#la-bound-fp-s.txt fldle.s mask=0x38750000
#0x38750000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fldle.s frD, RJsrc, RKsrc is op15_31=0x70ea & frD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <load>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<load>
frD = sext(*[ram]:4 vaddr);
}
#la-bound-fp-s.txt fstgt.s mask=0x38760000
#0x38760000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstgt.s frD, RJsrc, RKsrc is op15_31=0x70ec & frD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr > RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:4 vaddr = frD;
}
#la-bound-fp-s.txt fstle.s mask=0x38770000
#0x38770000 0xffff8000 f0:5, r5:5, r10:5 ['freg0_5_s0', 'reg5_5_s0', 'reg10_5_s0']
:fstle.s frD, RJsrc, RKsrc is op15_31=0x70ee & frD & RJsrc & RKsrc {
local vaddr = RJsrc;
if (vaddr <= RKsrc) goto <store>;
bound_check_exception(RJsrc, RKsrc);
goto inst_next;
<store>
*[ram]:4 vaddr = frD;
}

View file

@ -0,0 +1,578 @@
define endian=little;
define alignment=4;
define space ram type=ram_space size=$(REGSIZE) default;
define space iocsr type=ram_space size=$(REGSIZE);
define space register type=register_space size=4;
define register offset=0x0 size=$(REGSIZE) [
pc scr0 scr1 scr2 scr3
];
define register offset=0x40 size=1 [
fcc0 fcc1 fcc2 fcc3 fcc4 fcc5 fcc6 fcc7
];
define register offset=0x48 size=4 [
fcsr
];
# ABI names:
# "$zero", "$ra", "$tp", "$sp", "$a0", "$a1", "$a2", "$a3",
# "$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3",
# "$t4", "$t5", "$t6", "$t7", "$t8", "$x", "$fp", "$s0",
# "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$s8",
# GPR General Purpose Registers
define register offset=0x100 size=$(REGSIZE) [
zero ra tp sp a0 a1 a2 a3
a4 a5 a6 a7 t0 t1 t2 t3
t4 t5 t6 t7 t8 r21 fp s0
s1 s2 s3 s4 s5 s6 s7 s8
];
@ifdef LA64
define register offset=0x100 size=4 [
r0_lo r0_hi ra_lo ra_hi tp_lo tp_hi sp_lo sp_hi
a0_lo a0_hi a1_lo a1_hi a2_lo a2_hi a3_lo a3_hi
a4_lo a4_hi a5_lo a5_hi a6_lo a6_hi a7_lo a7_hi
t0_lo t0_hi t1_lo t1_hi t2_lo t2_hi t3_lo t3_hi
t4_lo t4_hi t5_lo t5_hi t6_lo t6_hi t7_lo t7_hi
t8_lo t8_hi r21_lo r21_hi fp_lo fp_hi s0_lo s0_hi
s1_lo s1_hi s2_lo s2_hi s3_lo s3_hi s4_lo s4_hi
s5_lo s5_hi s6_lo s6_hi s7_lo s7_hi s8_lo s8_hi
];
@endif
# Floating Point registers (either 32- or 64-bit)
@if FREGSIZE == "4"
define register offset=0x1000 size=4 [
fa0 _ _ _ _ _ _ _ fa1 _ _ _ _ _ _ _
fa2 _ _ _ _ _ _ _ fa3 _ _ _ _ _ _ _
fa4 _ _ _ _ _ _ _ fa5 _ _ _ _ _ _ _
fa6 _ _ _ _ _ _ _ fa7 _ _ _ _ _ _ _
ft0 _ _ _ _ _ _ _ ft1 _ _ _ _ _ _ _
ft2 _ _ _ _ _ _ _ ft3 _ _ _ _ _ _ _
ft4 _ _ _ _ _ _ _ ft5 _ _ _ _ _ _ _
ft6 _ _ _ _ _ _ _ ft7 _ _ _ _ _ _ _
ft8 _ _ _ _ _ _ _ ft9 _ _ _ _ _ _ _
ft10 _ _ _ _ _ _ _ ft11 _ _ _ _ _ _ _
ft12 _ _ _ _ _ _ _ ft13 _ _ _ _ _ _ _
ft14 _ _ _ _ _ _ _ ft15 _ _ _ _ _ _ _
fs0 _ _ _ _ _ _ _ fs1 _ _ _ _ _ _ _
fs2 _ _ _ _ _ _ _ fs3 _ _ _ _ _ _ _
fs4 _ _ _ _ _ _ _ fs5 _ _ _ _ _ _ _
fs6 _ _ _ _ _ _ _ fs7 _ _ _ _ _ _ _
];
define register offset=0x1000 size=8 [
fa0_1 _ _ _ fa2_3 _ _ _
fa4_5 _ _ _ fa6_7 _ _ _
ft8_9 _ _ _ ft10_11 _ _ _
ft12_13 _ _ _ ft14_15 _ _ _
ft16_17 _ _ _ ft18_19 _ _ _
ft20_21 _ _ _ ft22_23 _ _ _
fs24_25 _ _ _ fs26_27 _ _ _
fs28_29 _ _ _ fs30_31 _ _ _
];
@else
define register offset=0x1000 size=4 [
fa0_lo _ _ _ _ _ _ _ fa1_lo _ _ _ _ _ _ _
fa2_lo _ _ _ _ _ _ _ fa3_lo _ _ _ _ _ _ _
fa4_lo _ _ _ _ _ _ _ fa5_lo _ _ _ _ _ _ _
fa6_lo _ _ _ _ _ _ _ fa7_lo _ _ _ _ _ _ _
ft0_lo _ _ _ _ _ _ _ ft1_lo _ _ _ _ _ _ _
ft2_lo _ _ _ _ _ _ _ ft3_lo _ _ _ _ _ _ _
ft4_lo _ _ _ _ _ _ _ ft5_lo _ _ _ _ _ _ _
ft6_lo _ _ _ _ _ _ _ ft7_lo _ _ _ _ _ _ _
ft8_lo _ _ _ _ _ _ _ ft9_lo _ _ _ _ _ _ _
ft10_lo _ _ _ _ _ _ _ ft11_lo _ _ _ _ _ _ _
ft12_lo _ _ _ _ _ _ _ ft13_lo _ _ _ _ _ _ _
ft14_lo _ _ _ _ _ _ _ ft15_lo _ _ _ _ _ _ _
fs0_lo _ _ _ _ _ _ _ fs1_lo _ _ _ _ _ _ _
fs2_lo _ _ _ _ _ _ _ fs3_lo _ _ _ _ _ _ _
fs4_lo _ _ _ _ _ _ _ fs5_lo _ _ _ _ _ _ _
fs6_lo _ _ _ _ _ _ _ fs7_lo _ _ _ _ _ _ _
];
define register offset=0x1000 size=8 [
fa0 _ _ _ fa1 _ _ _ fa2 _ _ _ fa3 _ _ _
fa4 _ _ _ fa5 _ _ _ fa6 _ _ _ fa7 _ _ _
ft0 _ _ _ ft1 _ _ _ ft2 _ _ _ ft3 _ _ _
ft4 _ _ _ ft5 _ _ _ ft6 _ _ _ ft7 _ _ _
ft8 _ _ _ ft9 _ _ _ ft10 _ _ _ ft11 _ _ _
ft12 _ _ _ ft13 _ _ _ ft14 _ _ _ ft15 _ _ _
fs0 _ _ _ fs1 _ _ _ fs2 _ _ _ fs3 _ _ _
fs4 _ _ _ fs5 _ _ _ fs6 _ _ _ fs7 _ _ _
];
@endif #FREGSIZE == 32
# SIMD eXtension 256-bit registers (lsx)
# overlaps the floating point registers above
define register offset=0x1000 size=16 [
v0 _ v1 _ v2 _ v3 _ v4 _ v5 _ v6 _ v7 _
v8 _ v9 _ v10 _ v11 _ v12 _ v13 _ v14 _ v15 _
v16 _ v17 _ v18 _ v19 _ v20 _ v21 _ v22 _ v23 _
v24 _ v25 _ v26 _ v27 _ v28 _ v29 _ v30 _ v31 _
];
# AdVanced SIMD eXtension 256-bit registers (lasx)
# overlaps the floating point registers above
define register offset=0x1000 size=32 [
x0 x1 x2 x3 x4 x5 x6 x7
x8 x9 x10 x11 x12 x13 x14 x15
x16 x17 x18 x19 x20 x21 x22 x23
x24 x25 x26 x27 x28 x29 x30 x31
];
@define CSR_OFFSET "0x2000" #used for the csr instructions csrxchg/cssrd/cssrw
define register offset=$(CSR_OFFSET) size=$(REGSIZE) [
crmd prmd euen misc ecfg estat era badv
badi csr9 csr10 csr11 eentry csr13 csr14 csr15
tlbidx tlbehi tlbelo0 tlbelo1 csr20 csr21 csr22 csr23
asid pgdl pgdh pgd pwcl pwch stlbps rvacfg
cpuid prcfg1 prcfg2 prcfg3 csr36 csr37 csr38 csr39
csr40 csr41 csr42 csr43 csr44 csr45 csr46 csr47
save0 save1 save2 save3 save4 save5 save6 save7
save8 save9 save10 save11 save12 save13 save14 save15
tid tcfg tval cntc ticlr csr69 csr70 csr71
csr72 csr73 csr74 csr75 csr76 csr78 csr79
csr80 csr81 csr82 csr83 csr84 csr85 csr86 csr87
csr88 csr89 csr90 csr91 csr92 csr93 csr94 csr95
llbctl csr97 csr98 csr99 csr100 csr101 csr102 csr103
csr104 csr105 csr106 csr107 csr108 csr109 csr110 csr111
csr112 csr113 csr114 csr115 csr116 csr117 csr118 csr119
csr120 csr121 csr122 csr123 csr124 csr125 csr126 csr127
impctl1 impctl2 csr130 csr131 csr132 csr133 csr134 csr135
tlbrentry tlbrbadv tlbrera tlbrsave tlbrelo0 tlbrelo1 tlbrehi tlbrprmd
merrctl merrinfo1 merrinfo2 merrentry merrera merrsave csr150 csr151
ctag csr153 csr154 csr155 csr156 csr157 csr158 csr159
csr160 csr161 csr162 csr163 csr164 csr165 csr166 csr167
csr168 csr169 csr170 csr171 csr172 csr173 csr174 csr175
csr176 csr177 csr178 csr179 csr180 csr181 csr182 csr183
csr184 csr185 csr186 csr187 csr188 csr189 csr190 csr191
csr192 csr193 csr194 csr195 csr196 csr197 csr198 csr199
csr200 csr201 csr202 csr203 csr204 csr205 csr206 csr207
csr208 csr209 csr210 csr211 csr212 csr213 csr214 csr215
csr216 csr217 csr218 csr219 csr220 csr221 csr222 csr223
csr224 csr225 csr226 csr227 csr228 csr229 csr230 csr231
csr232 csr233 csr234 csr235 csr236 csr237 csr238 csr239
csr240 csr241 csr242 csr243 csr244 csr245 csr246 csr247
csr248 csr249 csr250 csr251 csr252 csr253 csr254 csr255
csr256 csr257 csr258 csr259 csr260 csr261 csr262 csr263
];
# Dummy registers for floating point comparison
define register offset=0x5000 size=4 [
FCMP1 FCMP2
];
define register offset=0x5008 size=1 [
FCMPR
];
define register offset=0x5100 size=8 [
DCMP1 DCMP2
];
define register offset=0x5110 size=1 [
DCMPR
];
define register offset=0x50 size=4 contextreg;
define context contextreg
phase = (0,1) ;
define token instr(32)
instword = ( 0,31)
op26_31 = (26,31)
op25_31 = (25,31)
op24_31 = (24,31)
op23_31 = (23,31)
op22_31 = (22,31)
op21_31 = (21,31)
op20_31 = (20,31)
op19_31 = (19,31)
op18_31 = (18,31)
op18_19 = (18,19)
op17_31 = (17,31)
op16_31 = (16,31)
op15_31 = (15,31)
op15_15 = (15,15)
op14_31 = (14,31)
op13_31 = (13,31)
op12_31 = (12,31)
op11_31 = (11,31)
op10_31 = (10,31)
op8_31 = ( 8,31)
op8_9 = ( 8, 9)
op7_31 = ( 7,31)
op5_9 = ( 5, 9)
op5_31 = ( 5,31)
op4_4 = ( 4, 4)
op3_4 = ( 3, 4)
op2_4 = ( 2, 4)
op0_2 = ( 0, 2)
op0_4 = ( 0, 4)
op0_31 = ( 0,31)
ccf = (16,19)
ccf_s = (15,15)
simm5_20 = ( 5,24) signed
simm5_13 = ( 5,17) signed
simm10_9 = (10,18) signed
simm10_8 = (10,17) signed
simm10_5 = (10,14) signed
simm10_14 = (10,23) signed
simm10_16 = (10,25) signed
simm10_12 = (10,21) signed
simm10_11 = (10,20) signed
simm10_10 = (10,19) signed
simm0_5 = ( 0, 4) signed
simm0_10 = ( 0, 9) signed
rK = (10,14)
rK32 = (10,14)
rJ = ( 5, 9)
rJ32 = ( 5, 9)
rD = ( 0, 4)
rD32 = ( 0, 4)
xrK = (10,14)
xrJ = ( 5, 9)
xrD = ( 0, 4)
xrA = (15,19)
vrK = (10,14)
vrJ = ( 5, 9)
vrD = ( 0, 4)
vrA = (15,19)
lbtrJ = ( 5, 6)
lbtrD = ( 0, 1)
frK = (10,14)
frJ = ( 5, 9)
frD = ( 0, 4)
frA = (15,19)
drK = (10,14)
drJ = ( 5, 9)
drD = ( 0, 4)
drA = (15,19)
fccJ = ( 5, 7)
fccD = ( 0, 2)
fccA = (15,17)
imm5_5 = ( 5, 9)
imm5_3 = ( 5, 7)
imm18_5 = (18,22)
imm18_4 = (18,21)
imm18_3 = (18,20)
imm18_2 = (18,19)
imm18_1 = (18,18)
imm16_6 = (16,21)
imm16_5 = (16,20)
imm15_3 = (15,17)
imm15_2 = (15,16)
imm10_8 = (10,17)
imm10_7 = (10,16)
imm10_6 = (10,15)
imm10_5 = (10,14)
imm10_4 = (10,13)
imm10_3 = (10,12)
imm10_2 = (10,11)
imm10_16 = (10,25)
imm10_14 = (10,23)
imm10_12 = (10,21)
imm10_1 = (10,10)
imm0_5 = ( 0, 4)
imm0_4 = ( 0, 3)
imm0_15 = ( 0,14)
;
attach variables [ rD rJ rK ] [
zero ra tp sp a0 a1 a2 a3
a4 a5 a6 a7 t0 t1 t2 t3
t4 t5 t6 t7 t8 r21 fp s0
s1 s2 s3 s4 s5 s6 s7 s8
];
@ifdef LA64
attach variables [ rD32 rJ32 rK32 ] [
r0_lo ra_lo tp_lo sp_lo
a0_lo a1_lo a2_lo a3_lo
a4_lo a5_lo a6_lo a7_lo
t0_lo t1_lo t2_lo t3_lo
t4_lo t5_lo t6_lo t7_lo
t8_lo r21_lo fp_lo s0_lo
s1_lo s2_lo s3_lo s4_lo
s5_lo s6_lo s7_lo s8_lo
];
@else
# For LA32 these are the same as rD, rJ, rK
attach variables [ rD32 rJ32 rK32 ] [
zero ra tp sp a0 a1 a2 a3
a4 a5 a6 a7 t0 t1 t2 t3
t4 t5 t6 t7 t8 r21 fp s0
s1 s2 s3 s4 s5 s6 s7 s8
];
@endif
@if FREGSIZE == "8"
# For 64-bit floating point single instruction operands use only the low part
attach variables [ frD frJ frK ] [
fa0_lo fa1_lo fa2_lo fa3_lo fa4_lo fa5_lo fa6_lo fa7_lo
ft0_lo ft1_lo ft2_lo ft3_lo ft4_lo ft5_lo ft6_lo ft7_lo
ft8_lo ft9_lo ft10_lo ft11_lo ft12_lo ft13_lo ft14_lo ft15_lo
fs0_lo fs1_lo fs2_lo fs3_lo fs4_lo fs5_lo fs6_lo fs7_lo
];
attach variables [ drD drJ drK ] [
fa0 fa1 fa2 fa3 fa4 fa5 fa6 fa7
ft0 ft1 ft2 ft3 ft4 ft5 ft6 ft7
ft8 ft9 ft10 ft11 ft12 ft13 ft14 ft15
fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7
];
@else
attach variables [ frD frJ frK ] [
fa0 fa1 fa2 fa3 fa4 fa5 fa6 fa7
ft0 ft1 ft2 ft3 ft4 ft5 ft6 ft7
ft8 ft9 ft10 ft11 ft12 ft13 ft14 ft15
fs0 fs1 fs2 fs3 fs4 fs5 fs6 fs7
];
# For 64-bit floating point Double instruction operands need to bond two 32-bit FPRs
attach variables [ drD drJ drK ] [
fa0_1 _ fa2_3 _ fa4_5 _ fa6_7 _
ft8_9 _ ft10_11 _ ft12_13 _ ft14_15 _
ft16_17 _ ft18_19 _ ft20_21 _ ft22_23 _
fs24_25 _ fs26_27 _ fs28_29 _ fs30_31 _
];
@endif
attach variables [vrD vrJ vrK vrA] [
v0 v1 v2 v3 v4 v5 v6 v7
v8 v9 v10 v11 v12 v13 v14 v15
v16 v17 v18 v19 v20 v21 v22 v23
v24 v25 v26 v27 v28 v29 v30 v31
];
attach variables [xrD xrJ xrK xrA] [
x0 x1 x2 x3 x4 x5 x6 x7
x8 x9 x10 x11 x12 x13 x14 x15
x16 x17 x18 x19 x20 x21 x22 x23
x24 x25 x26 x27 x28 x29 x30 x31
];
attach variables [ fccD fccJ fccA] [
fcc0 fcc1 fcc2 fcc3 fcc4 fcc5 fcc6 fcc7
];
# Register subconstructors
RD: rD is rD { export rD; }
RDsrc: rD is rD { export rD; }
RDsrc: rD is rD & rD=0 { export 0:$(REGSIZE); }
RJ: rJ is rJ { export rJ; }
RJsrc: rJ is rJ { export rJ; }
RJsrc: rJ is rJ & rJ=0 { export 0:$(REGSIZE); }
RK: rK is rK { export rK; }
RKsrc: rK is rK { export rK; }
RKsrc: rK is rK & rK=0 { export 0:$(REGSIZE); }
RD32: rD is rD & rD32 { export rD32; }
RD32src: rD is rD & rD32 { export rD32; }
RD32src: rD is rD & rD32=0 { export 0:4; }
RJ32: rJ is rJ & rJ32 { export rJ32; }
RJ32src: rJ is rJ & rJ32 { export rJ32; }
RJ32src: rJ is rJ & rJ32=0 { export 0:4; }
RK32: rK is rK & rK32 { export rK32; }
RK32src: rK is rK & rK32 { export rK32; }
RK32src: rK is rK & rK32=0 { export 0:4; }
@if FREGSIZE == "8"
FRD: drD is drD { export drD; }
FRJ: drJ is drJ { export drJ; }
FRK: drK is drK { export drK; }
@else
FRD: frD is frD { export frD; }
FRJ: frJ is frJ { export frJ; }
FRK: frK is frK { export frK; }
@endif
# Immediate operand sub-constructors
addu16_imm: val is simm10_16 [val = simm10_16 << 16;] { export *[const]:$(REGSIZE) val; }
alsl_shift: sa2 is imm15_2 [sa2 = imm15_2 + 1;] { export *[const]:1 sa2; }
ldst_addr: RJsrc(simm10_12) is RJsrc & simm10_12 { local vaddr:$(REGSIZE) = RJsrc + simm10_12; export vaddr; }
ldstptr_addr: RJsrc(voffs) is RJsrc & simm10_14 [voffs = (simm10_14 << 2);] { local vaddr:$(REGSIZE) = RJsrc + voffs; export vaddr; }
ldstx_addr: RJsrc(RKsrc) is RJsrc & RKsrc { local vaddr:$(REGSIZE) = RJsrc + RKsrc; export vaddr; }
pcadd2: reloffs is simm5_20 [reloffs = inst_start + (simm5_20 << 2);] { export *[const]:$(REGSIZE) reloffs; }
pcadd12: reloffs is simm5_20 [reloffs = inst_start + (simm5_20 << 12);] { export *[const]:$(REGSIZE) reloffs; }
pcala12: reloffs is simm5_20 [reloffs = (inst_start & ~0xfff) + (simm5_20 << 12);] { export *[const]:$(REGSIZE) reloffs; }
pcadd18: reloffs is simm5_20 [reloffs = inst_start + (simm5_20 << 18);] { export *[const]:$(REGSIZE) reloffs; }
Rel16: reloc is simm10_16 [ reloc = inst_start + (simm10_16 << 2); ] { export *:$(ADDRSIZE) reloc; }
Rel21: reloc is imm10_16 & simm0_5 [ reloc = inst_start + (((simm0_5 << 16) + imm10_16) << 2); ] { export *:$(ADDRSIZE) reloc; }
Rel26: reloc is imm10_16 & simm0_10 [ reloc = inst_start + (((simm0_10 << 16) | imm10_16) << 2); ] { export *:$(ADDRSIZE) reloc; }
RelJ16: RJsrc, simm10_16 is RJsrc & simm10_16 { local tmp:$(ADDRSIZE) = RJsrc + (simm10_16 << 2); export tmp; }
simm12i: immed is simm5_20 [immed = simm5_20 << 12; ] { export *[const]:$(REGSIZE) immed; }
simm32i: immed is simm5_20 [immed = simm5_20 << 32; ] { export *[const]:$(REGSIZE) immed; }
simm52i: immed is simm10_12 [immed = simm10_12 << 52; ] { export *[const]:$(REGSIZE) immed; }
# general pcodeops
define pcodeop break;
define pcodeop cpucfg;
define pcodeop addr_bound_exception;
define pcodeop bound_check_exception;
define pcodeop crc_ieee802.3;
define pcodeop crc_castagnoli;
define pcodeop dbcl;
define pcodeop dbar;
define pcodeop ibar;
define pcodeop iocsrrd;
define pcodeop iocsrwr;
define pcodeop preld_loadl1cache;
define pcodeop preld_storel1cache;
define pcodeop preld_nop;
define pcodeop preldx_loadl1cache;
define pcodeop preldx_storel1cache;
define pcodeop preldx_nop;
# param: 0 = low word, 1 = high word, 2 = both (for rdtime.d)
define pcodeop rdtime.counter;
define pcodeop rdtime.counterid;
define pcodeop syscall;
define pcodeop f_scaleb;
define pcodeop f_logb;
define pcodeop f_class;
define pcodeop round_even;
#
# MACROS
#
macro bitrev32(input, output) {
local v = input;
v = ((v & 0xffff0000) >> 16) | ((v & 0x0000ffff) << 16);
v = ((v & 0xff00ff00) >> 8) | ((v & 0x00ff00ff) << 8);
v = ((v & 0xf0f0f0f0) >> 4) | ((v & 0x0f0f0f0f) << 4);
v = ((v & 0xcccccccc) >> 2) | ((v & 0x33333333) << 2);
v = ((v & 0xaaaaaaaa) >> 1) | ((v & 0x55555555) << 1);
output = v;
}
macro bitrev64(input, output) {
local v = input;
v = ((v & 0xffffffff00000000) >> 32) | ((v & 0x00000000ffffffff) << 32);
v = ((v & 0xffff0000ffff0000) >> 16) | ((v & 0x0000ffff0000ffff) << 16);
v = ((v & 0xff00ff00ff00ff00) >> 8) | ((v & 0x00ff00ff00ff00ff) << 8);
v = ((v & 0xf0f0f0f0f0f0f0f0) >> 4) | ((v & 0x0f0f0f0f0f0f0f0f) << 4);
v = ((v & 0xcccccccccccccccc) >> 2) | ((v & 0x3333333333333333) << 2);
v = ((v & 0xaaaaaaaaaaaaaaaa) >> 1) | ((v & 0x5555555555555555) << 1);
output = v;
}
macro byterev(input, output) {
local v = input;
v = ((v & 0xf0) >> 4) | ((v & 0x0f) << 4);
v = ((v & 0xcc) >> 2) | ((v & 0x33) << 2);
v = ((v & 0xaa) >> 1) | ((v & 0x55) << 1);
output = v;
}
macro byterev32(input, output) {
local v = input;
v = ((v & 0xf0f0f0f0) >> 4) | ((v & 0x0f0f0f0f) << 4);
v = ((v & 0xcccccccc) >> 2) | ((v & 0x33333333) << 2);
v = ((v & 0xaaaaaaaa) >> 1) | ((v & 0x55555555) << 1);
output = v;
}
macro byterev64(input, output) {
local v = input;
v = ((v & 0xf0f0f0f0f0f0f0f0) >> 4) | ((v & 0x0f0f0f0f0f0f0f0f) << 4);
v = ((v & 0xcccccccccccccccc) >> 2) | ((v & 0x3333333333333333) << 2);
v = ((v & 0xaaaaaaaaaaaaaaaa) >> 1) | ((v & 0x5555555555555555) << 1);
output = v;
}
macro tzcount32(input, count) {
count = 32;
local v = input & (-input);
count = count - zext(v != 0);
count = count - 16 * zext((v & 0x0000ffff) != 0);
count = count - 8 * zext((v & 0x00ff00ff) != 0);
count = count - 4 * zext((v & 0x0f0f0f0f) != 0);
count = count - 2 * zext((v & 0x33333333) != 0);
count = count - 1 * zext((v & 0x55555555) != 0);
}
macro tzcount64(input, count) {
count = 64;
local v:8 = input & (-input);
count = count - 1 * zext(v != 0);
count = count - 32 * zext((v & 0x00000000ffffffff) != 0);
count = count - 16 * zext((v & 0x0000ffff0000ffff) != 0);
count = count - 8 * zext((v & 0x00ff00ff00ff00ff) != 0);
count = count - 4 * zext((v & 0x0f0f0f0f0f0f0f0f) != 0);
count = count - 2 * zext((v & 0x3333333333333333) != 0);
count = count - 1 * zext((v & 0x5555555555555555) != 0);
}

View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<integer_size value="4" />
<long_size value="8" />
<pointer_size value="8"/>
<float_size value="4" />
<double_size value="8" />
<long_double_size value="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
<entry size="16" alignment="16" />
</size_alignment_map>
</data_organization>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/>
<returnaddress>
<register name="ra"/>
</returnaddress>
<global>
<range space="ram"/>
<range space="register" first="0x2000" last="0x2fff"/>
</global>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input killedbycall="true">
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa7"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a0"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a1"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a2"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a5"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a6"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a7"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a2" piece2="a3"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a4" piece2="a5"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a6" piece2="a7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="8">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a0"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
</output>
<killedbycall>
<register name="t0"/>
<register name="t1"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
<register name="t8"/>
<register name="ft0"/>
<register name="ft1"/>
<register name="ft2"/>
<register name="ft3"/>
<register name="ft4"/>
<register name="ft5"/>
<register name="ft6"/>
<register name="ft7"/>
<register name="ft8"/>
<register name="ft9"/>
<register name="ft10"/>
<register name="ft11"/>
<register name="ft12"/>
<register name="ft13"/>
<register name="ft14"/>
<register name="ft15"/>
</killedbycall>
<unaffected>
<register name="s0"/>
<register name="s1"/>
<register name="s2"/>
<register name="s3"/>
<register name="s4"/>
<register name="s5"/>
<register name="s6"/>
<register name="s7"/>
<register name="s8"/>
<register name="sp"/>
<register name="fp"/>
<register name="fs0"/>
<register name="fs1"/>
<register name="fs2"/>
<register name="fs3"/>
<register name="fs4"/>
<register name="fs5"/>
<register name="fs6"/>
<register name="fs7"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>

View file

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<integer_size value="4" />
<long_size value="8" />
<pointer_size value="8"/>
<float_size value="4" />
<double_size value="8" />
<long_double_size value="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
<entry size="16" alignment="16" />
</size_alignment_map>
</data_organization>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/>
<global>
<range space="ram"/>
<range space="register" first="0x2000" last="0x2fff"/>
</global>
<returnaddress>
<register name="ra"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input killedbycall="true">
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa1"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa2"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa3"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa4"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa5"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa6"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa7"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa7"/>
</pentry>
<pentry minsize="5" maxsize="8" metatype="float">
<addr space="join" piece1="fa0" piece2="fa1"/>
</pentry>
<pentry minsize="5" maxsize="8" metatype="float">
<addr space="join" piece1="fa2" piece2="fa3"/>
</pentry>
<pentry minsize="5" maxsize="8" metatype="float">
<addr space="join" piece1="fa4" piece2="fa5"/>
</pentry>
<pentry minsize="5" maxsize="8" metatype="float">
<addr space="join" piece1="fa6" piece2="fa7"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a0"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a1"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a2"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a5"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a6"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a7"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a2" piece2="a3"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a4" piece2="a5"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a6" piece2="a7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="8">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="fa0"/>
</pentry>
<pentry minsize="5" maxsize="8" metatype="float">
<addr space="join" piece1="fa0" piece2="fa1"/>
</pentry>
<pentry minsize="1" maxsize="8">
<register name="a0"/>
</pentry>
<pentry minsize="9" maxsize="16">
<addr space="join" piece1="a0" piece2="a1"/>
</pentry>
</output>
<killedbycall>
<register name="t0"/>
<register name="t1"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
<register name="t8"/>
<register name="ft0"/>
<register name="ft1"/>
<register name="ft2"/>
<register name="ft3"/>
<register name="ft4"/>
<register name="ft5"/>
<register name="ft6"/>
<register name="ft7"/>
<register name="ft8"/>
<register name="ft9"/>
<register name="ft10"/>
<register name="ft11"/>
<register name="ft12"/>
<register name="ft13"/>
<register name="ft14"/>
<register name="ft15"/>
</killedbycall>
<unaffected>
<register name="s0"/>
<register name="s1"/>
<register name="s2"/>
<register name="s3"/>
<register name="s4"/>
<register name="s5"/>
<register name="s6"/>
<register name="s7"/>
<register name="s8"/>
<register name="sp"/>
<register name="fp"/>
<register name="fs0"/>
<register name="fs1"/>
<register name="fs2"/>
<register name="fs3"/>
<register name="fs4"/>
<register name="fs5"/>
<register name="fs6"/>
<register name="fs7"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,59 @@
define pcodeop gcsrxchg;
#lvz.txt gcsrxchg mask=0x05000000 [@lvz]
#0x05000000 0xff000000 r0:5, r5:5,u10:14 ['reg0_5_s0', 'reg5_5_s0', 'imm10_14_s0']
:gcsrxchg RD, RJsrc,imm10_14 is op24_31=0x5 & RD & RJsrc & imm10_14 {
RD = gcsrxchg(RD, RJsrc, imm10_14:$(REGSIZE));
}
define pcodeop gtlbclr;
#lvz.txt gtlbclr mask=0x06482001 [@lvz]
:gtlbclr is instword=0x06482001 {
gtlbclr();
}
define pcodeop gtlbflush;
#lvz.txt gtlbflush mask=0x06482401 [@lvz]
#0x06482401 0xffffffff ['']
:gtlbflush is instword=0x06482401 {
gtlbflush();
}
define pcodeop gtlbsrch;
#lvz.txt gtlbsrch mask=0x06482801 [@lvz]
:gtlbsrch is instword=0x06482801 {
gtlbsrch();
}
define pcodeop gtlbrd;
#lvz.txt gtlbrd mask=0x06482c01 [@lvz]
:gtlbrd is instword=0x06482c01 {
gtlbrd();
}
define pcodeop gtlbwr;
#lvz.txt gtlbwr mask=0x06483001 [@lvz]
:gtlbwr is instword=0x06483001 {
gtlbwr();
}
define pcodeop gtlbfill;
#lvz.txt gtlbfill mask=0x06483401 [@lvz]
:gtlbfill is instword=0x06483401 {
gtlbfill();
}
define pcodeop hvcl;
#lvz.txt hypcall mask=0x002b8000 [@lvz, @orig_name=hvcl]
#0x002b8000 0xffff8000 u0:15 ['imm0_15_s0']
:hvcl imm0_15 is op15_31=0x57 & imm0_15 {
hvcl(imm0_15:$(REGSIZE));
}

View file

@ -0,0 +1,181 @@
@LoongArch-Vol1-EN.pdf[LoongArch Reference Manual - Volume 1: Basic Architecture]
add, 23
sub, 23
addi, 24
addu16id, 24
alsl, 25
lu12i.w, 26
lu32i.d, 26
lu52i.d, 26
slt, 26
sltu, 26
slti, 27
sltui, 27
pcaddi, 28
pcaddu12i, 28
pcaddu18i, 28
pcalau12i, 28
and, 29
or, 29
nor, 29
xor, 29
andn, 29
orn, 29
andi, 30
ori, 30
xori, 30
mul, 31
mulh, 31
mulw, 32
div, 32
mod, 32
sll.w, 34
srl.w, 34
sra.w, 34
rotr.w, 34
slli.w, 35
srli.w, 35
srai.w, 35
rotri.w, 35
sll.d, 36
srl.d, 36
sra.d, 36
rotr.d, 36
slli.d, 37
srli.d, 37
srai.d, 37
rotri.d, 37
ext.w.b, 38
ext.w.h, 38
clo, 38
clz, 38
cto, 38
ctz, 38
bytepick, 40
revb, 40
revh, 41
bitrev.4b, 42
bitrev.8b, 42
bitrev.w, 43
bitrev.d, 43
bstrins, 43
bstrpick, 44
maskeqz, 44
masknez, 44
beq, 45
bne, 45
blt, 45
bge, 45
bltu, 45
bgeu, 45
beqz, 46
bnez, 46
b, 47
bl, 47
jirl, 48
ld, 49
st, 49
ldx, 51
stx, 51
ldptr, 53
stptr, 53
preld, 54
preldx, 55
lgdt, 56
ldle, 56
stgt, 56
stle, 56
amswap, 60
amadd, 60
amand, 60
amor, 60
amxor, 60
ammax, 60
ammin, 60
ll, 62
sc, 62
dbar, 62
ibar, 63
crc, 63
crcc, 63
syscall, 64
break, 64
asrtle, 65
asrtgt, 65
rdtime, 65
rdtimel, 65
rdtimeh, 65
cpucfg, 65
fadd, 78
fsub, 78
fmul, 78
fmadd, 80
fmsub, 80
fnmadd, 80
fnmsub, 80
fmax, 81
fmin, 81
fmaxa, 82
fmina, 82
fabs, 83
fneg, 83
fsqrt, 83
frecip, 83
frsqrt, 83
fscaleb, 85
flogb, 85
fcopysign, 85
fclass, 86
fcmp, 86
fcvt, 88
ffint, 88
ftint, 88
ftintrm, 90
ftintrp, 90
ftintrz, 90
ftintrne, 90
frint, 92
fmov, 93
fsel, 94
movgr2fr, 94
movgr2frh, 94
movfr2gr, 95
movfrh2gr, 95
movgr2fcsr, 95
movfcsr2gr, 95
movfr2cf, 96
movcf2fr, 96
movgr2cf, 96
movcf2gr, 96
bceqz, 97
bcnez, 97
fld, 97
fst, 97
fldx, 98
fstx, 98
fldgt, 100
fldle, 100
fstgt, 100
fstle, 100
csrrd, 103
csrwr, 103
csrxchg, 103
iocsrrd, 104
iocsrwr, 104
cacop, 104
tlbsrch, 105
tlbrd, 106
tlbwr, 106
tlbfill, 106
tlbclr, 107
tlbflush, 107
invtlb, 107
lddir, 108
ldpte, 108
ertn, 109
dbcl, 110
idle, 110

View file

@ -0,0 +1,38 @@
<patternlist>
<patternpairs totalbits="32" postbits="16">
<!-- Higher confidence patterns, after a return and more defined bits -->
<prepatterns>
<data>0x20 0x00 0x00 0x4c</data> <!-- ret -->
</prepatterns>
<postpatterns>
<data>0x63 ......00 111..... 0x02 01100001 .....000 11...... 0x29 </data> <!-- addi.d sp sp,-imm; st.d ra,sp(imm8)-->
<funcstart/>
</postpatterns>
</patternpairs>
<patternpairs totalbits="32" postbits="16">
<!-- Medium confidence, more bits, but prepattern are jumps, not return -->
<prepatterns>
<data> 11111111 ......11 ........ 01010011 </data> <!-- b imm , backwards a small amount -->
<data> 0x80 0x01 0x00 0x4c </data> <!-- jr t0 -->
</prepatterns>
<postpatterns>
<data>0x63 ......00 111..... 0x02 </data> <!-- addi.d sp sp,-imm; -->
<possiblefuncstart/>
</postpatterns>
</patternpairs>
<patternpairs totalbits="32" postbits="16">
<!-- Higher confidence patterns, after a return and more defined bits -->
<prepatterns>
<data>0x20 0x00 0x00 0x4c</data> <!-- ret -->
</prepatterns>
<postpatterns>
<data>0x63 ......00 111..... 0x02 </data> <!-- addi.d sp sp,-imm; -->
<possiblefuncstart/>
</postpatterns>
</patternpairs>
</patternlist>

View file

@ -0,0 +1,5 @@
<patternconstraints>
<language id="Loongarch:LE:*:*">
<patternfile>loongarch_patterns.xml</patternfile>
</language>
</patternconstraints>

View file

@ -0,0 +1,144 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.analysis;
import ghidra.framework.options.Options;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Processor;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.*;
import ghidra.program.util.SymbolicPropogator;
import ghidra.program.util.VarnodeContext;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class LoongsonAnalyzer extends ConstantPropagationAnalyzer {
private Register linkRegister;
private final static String PROCESSOR_NAME = "Loongarch";
public LoongsonAnalyzer() {
super(PROCESSOR_NAME);
}
@Override
public boolean canAnalyze(Program program) {
boolean canAnalyze = program.getLanguage()
.getProcessor()
.equals(Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME));
if (!canAnalyze) {
return false;
}
linkRegister = program.getProgramContext().getRegister("ra");
return true;
}
@Override
public AddressSet flowConstants(final Program program, final Address flowStart,
AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor)
throws CancelledException {
// follow all flows building up context
// use context to fill out addresses on certain instructions
ConstantPropagationContextEvaluator eval =
new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption) {
/**
* Check if there are any data references to this location.
* @param program
* @param addr
* @return true if there are any data references to addr
*/
private boolean hasDataReferenceTo(Program program, Address addr) {
ReferenceManager refMgr = program.getReferenceManager();
if (!refMgr.hasReferencesTo(addr)) {
return false;
}
ReferenceIterator referencesTo = refMgr.getReferencesTo(addr);
while (referencesTo.hasNext()) {
Reference reference = referencesTo.next();
if (reference.getReferenceType().isData()) {
return true;
}
}
return false;
}
private boolean isLinkRegister(VarnodeContext context, Varnode pcVal) {
return (pcVal.isRegister() &&
pcVal.getAddress().equals(linkRegister.getAddress())) ||
(context.isSymbol(pcVal) && pcVal.getAddress()
.getAddressSpace()
.getName()
.equals(linkRegister.getName()) &&
pcVal.getOffset() == 0);
}
@Override
public boolean evaluateDestination(VarnodeContext context, Instruction instruction) {
return super.evaluateDestination(context, instruction);
}
@Override
public boolean evaluateReturn(Varnode retVN, VarnodeContext context,
Instruction instruction) {
// check if a return is actually returning, or is branching with a constant PC
// if flow already overridden, don't override again
if (instruction.getFlowOverride() != FlowOverride.NONE) {
return false;
}
if (retVN != null && context.isConstant(retVN)) {
long offset = retVN.getOffset();
if (offset > 3 && offset != -1) {
FlowOverride flowOverride = FlowOverride.CALL_RETURN;
// need to override the return flow to a branch
instruction.setFlowOverride(flowOverride);
// need to analyze this flow again with the new return tag
AutoAnalysisManager aMgr= AutoAnalysisManager.getAnalysisManager(program);
aMgr.codeDefined(flowStart);
}
}
return false;
}
};
eval.setTrustWritableMemory(trustWriteMemOption)
.setMinpeculativeOffset(minSpeculativeRefAddress)
.setMaxSpeculativeOffset(maxSpeculativeRefAddress)
.setMinStoreLoadOffset(minStoreLoadRefAddress)
.setCreateComplexDataFromPointers(createComplexDataFromPointers);
AddressSet resultSet = symEval.flowConstants(flowStart, flowSet, eval, true, monitor);
return resultSet;
}
@Override
public void optionsChanged(Options options, Program program) {
super.optionsChanged(options, program);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Loongarch64_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Loongarch:LE:64:lp64d";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Loongarch64_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Loongarch64_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Loongarch64_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Loongarch64_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Loongarch:LE:64:lp64d";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Loongarch64_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Loongarch64_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Loongarch64_O3_EmulatorTest.class);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Loongarch64f_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Loongarch:LE:64:lp64f";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Loongarch64f_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Loongarch64f_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Loongarch64f_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Loongarch64f_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Loongarch:LE:64:lp64f";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Loongarch64f_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Loongarch64f_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Loongarch64f_O3_EmulatorTest.class);
}
}