mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 04:29:49 +00:00
2003-06-03 Andrew Cagney <cagney@redhat.com>
Contributed by Red Hat. * frv.cpu: New file. Written by Dave Brolley, Catherine Moore, and Eric Christopher. * frv.opc: New file. Written by Catherine Moore, and Dave Brolley. * simplify.inc: New file. Written by Doug Evans.
This commit is contained in:
parent
b814bbcbee
commit
9aab5aa3a0
@ -1,3 +1,12 @@
|
||||
2003-06-03 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
Contributed by Red Hat.
|
||||
* frv.cpu: New file. Written by Dave Brolley, Catherine Moore,
|
||||
and Eric Christopher.
|
||||
* frv.opc: New file. Written by Catherine Moore, and Dave
|
||||
Brolley.
|
||||
* simplify.inc: New file. Written by Doug Evans.
|
||||
|
||||
2003-05-02 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* New file.
|
||||
|
8078
cpu/frv.cpu
Normal file
8078
cpu/frv.cpu
Normal file
File diff suppressed because it is too large
Load Diff
946
cpu/frv.opc
Normal file
946
cpu/frv.opc
Normal file
@ -0,0 +1,946 @@
|
||||
/* Fujitsu FRV opcode support, for GNU Binutils. -*- C -*-
|
||||
|
||||
Copyright 2003 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Red Hat Inc; developed under contract from Fujitsu.
|
||||
|
||||
This file is part of the GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/* This file is an addendum to frv.cpu. Heavy use of C code isn't
|
||||
appropriate in .cpu files, so it resides here. This especially applies
|
||||
to assembly/disassembly where parsing/printing can be quite involved.
|
||||
Such things aren't really part of the specification of the cpu, per se,
|
||||
so .cpu files provide the general framework and .opc files handle the
|
||||
nitty-gritty details as necessary.
|
||||
|
||||
Each section is delimited with start and end markers.
|
||||
|
||||
<arch>-opc.h additions use: "-- opc.h"
|
||||
<arch>-opc.c additions use: "-- opc.c"
|
||||
<arch>-asm.c additions use: "-- asm.c"
|
||||
<arch>-dis.c additions use: "-- dis.c"
|
||||
<arch>-ibd.h additions use: "-- ibd.h"
|
||||
*/
|
||||
|
||||
/* -- opc.h */
|
||||
|
||||
#undef CGEN_DIS_HASH_SIZE
|
||||
#define CGEN_DIS_HASH_SIZE 128
|
||||
#undef CGEN_DIS_HASH
|
||||
#define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127)
|
||||
|
||||
/* Vliw support. */
|
||||
#define FRV_VLIW_SIZE 4 /* fr500 has largest vliw size of 4. */
|
||||
typedef CGEN_ATTR_VALUE_TYPE VLIW_COMBO[FRV_VLIW_SIZE];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int next_slot;
|
||||
int constraint_violation;
|
||||
unsigned long mach;
|
||||
unsigned long elf_flags;
|
||||
CGEN_ATTR_VALUE_TYPE *unit_mapping;
|
||||
VLIW_COMBO *current_vliw;
|
||||
CGEN_ATTR_VALUE_TYPE major[FRV_VLIW_SIZE];
|
||||
} FRV_VLIW;
|
||||
|
||||
int frv_is_branch_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
|
||||
int frv_is_float_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
|
||||
int frv_is_media_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
|
||||
int frv_is_branch_insn PARAMS ((const CGEN_INSN *));
|
||||
int frv_is_float_insn PARAMS ((const CGEN_INSN *));
|
||||
int frv_is_media_insn PARAMS ((const CGEN_INSN *));
|
||||
void frv_vliw_reset PARAMS ((FRV_VLIW *, unsigned long mach, unsigned long elf_flags));
|
||||
int frv_vliw_add_insn PARAMS ((FRV_VLIW *, const CGEN_INSN *));
|
||||
int spr_valid PARAMS ((long));
|
||||
/* -- */
|
||||
|
||||
/* -- opc.c */
|
||||
#include "elf/frv.h"
|
||||
|
||||
static int match_unit
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, CGEN_ATTR_VALUE_TYPE));
|
||||
static int match_vliw
|
||||
PARAMS ((VLIW_COMBO *, VLIW_COMBO *, int));
|
||||
static VLIW_COMBO * add_next_to_vliw
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
|
||||
static int find_major_in_vliw
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
|
||||
static int fr400_check_insn_major_constraints
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
|
||||
static int fr500_check_insn_major_constraints
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
|
||||
static int check_insn_major_constraints
|
||||
PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
|
||||
|
||||
int
|
||||
frv_is_branch_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
|
||||
{
|
||||
switch (mach)
|
||||
{
|
||||
case bfd_mach_fr400:
|
||||
if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6)
|
||||
return 1; /* is a branch */
|
||||
break;
|
||||
default:
|
||||
if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6)
|
||||
return 1; /* is a branch */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* not a branch */
|
||||
}
|
||||
|
||||
int
|
||||
frv_is_float_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
|
||||
{
|
||||
switch (mach)
|
||||
{
|
||||
case bfd_mach_fr400:
|
||||
return 0; /* No float insns */
|
||||
default:
|
||||
if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8)
|
||||
return 1; /* is a float insn */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* not a branch */
|
||||
}
|
||||
|
||||
int
|
||||
frv_is_media_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
|
||||
{
|
||||
switch (mach)
|
||||
{
|
||||
case bfd_mach_fr400:
|
||||
if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2)
|
||||
return 1; /* is a media insn */
|
||||
break;
|
||||
default:
|
||||
if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8)
|
||||
return 1; /* is a media insn */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* not a branch */
|
||||
}
|
||||
|
||||
int
|
||||
frv_is_branch_insn (const CGEN_INSN *insn)
|
||||
{
|
||||
if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
|
||||
bfd_mach_fr400))
|
||||
return 1;
|
||||
if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
|
||||
bfd_mach_fr500))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
frv_is_float_insn (const CGEN_INSN *insn)
|
||||
{
|
||||
if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
|
||||
bfd_mach_fr400))
|
||||
return 1;
|
||||
if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
|
||||
bfd_mach_fr500))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
frv_is_media_insn (const CGEN_INSN *insn)
|
||||
{
|
||||
if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
|
||||
bfd_mach_fr400))
|
||||
return 1;
|
||||
if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
|
||||
bfd_mach_fr500))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This table represents the allowable packing for vliw insns for the fr400.
|
||||
The fr400 has only 2 vliw slots. Represent this by not allowing any insns
|
||||
in slots 2 and 3.
|
||||
Subsets of any given row are also allowed. */
|
||||
static VLIW_COMBO fr400_allowed_vliw[] =
|
||||
{
|
||||
/* slot0 slot1 slot2 slot3 */
|
||||
{ UNIT_I0, UNIT_I1, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_I0, UNIT_FM0, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_I0, UNIT_B0, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_FM0, UNIT_FM1, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_FM0, UNIT_B0, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_B0, UNIT_NIL, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }
|
||||
};
|
||||
|
||||
/* This table represents the allowable packing for vliw insns for the fr500.
|
||||
Subsets of any given row are also allowed. */
|
||||
static VLIW_COMBO fr500_allowed_vliw[] =
|
||||
{
|
||||
/* slot0 slot1 slot2 slot3 */
|
||||
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1 },
|
||||
{ UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0 },
|
||||
{ UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0 },
|
||||
{ UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1 },
|
||||
{ UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 },
|
||||
{ UNIT_I0, UNIT_B0, UNIT_B1, UNIT_NIL },
|
||||
{ UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1 },
|
||||
{ UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL },
|
||||
{ UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL },
|
||||
{ UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }
|
||||
};
|
||||
|
||||
/* Some insns are assigned specialized implementation units which map to
|
||||
different actual implementation units on different machines. These
|
||||
tables perform that mapping. */
|
||||
static CGEN_ATTR_VALUE_TYPE fr400_unit_mapping[] =
|
||||
{
|
||||
/* unit in insn actual unit */
|
||||
/* NIL */ UNIT_NIL,
|
||||
/* I0 */ UNIT_I0,
|
||||
/* I1 */ UNIT_I1,
|
||||
/* I01 */ UNIT_I01,
|
||||
/* FM0 */ UNIT_FM0,
|
||||
/* FM1 */ UNIT_FM1,
|
||||
/* FM01 */ UNIT_FM01,
|
||||
/* B0 */ UNIT_B0, /* branches only in B0 unit. */
|
||||
/* B1 */ UNIT_B0,
|
||||
/* B01 */ UNIT_B0,
|
||||
/* C */ UNIT_C,
|
||||
/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */
|
||||
/* LOAD */ UNIT_I0 /* load only in I0 unit. */
|
||||
};
|
||||
|
||||
static CGEN_ATTR_VALUE_TYPE fr500_unit_mapping[] =
|
||||
{
|
||||
/* unit in insn actual unit */
|
||||
/* NIL */ UNIT_NIL,
|
||||
/* I0 */ UNIT_I0,
|
||||
/* I1 */ UNIT_I1,
|
||||
/* I01 */ UNIT_I01,
|
||||
/* FM0 */ UNIT_FM0,
|
||||
/* FM1 */ UNIT_FM1,
|
||||
/* FM01 */ UNIT_FM01,
|
||||
/* B0 */ UNIT_B0,
|
||||
/* B1 */ UNIT_B1,
|
||||
/* B01 */ UNIT_B01,
|
||||
/* C */ UNIT_C,
|
||||
/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */
|
||||
/* LOAD */ UNIT_I01 /* load in I0 or I1 unit. */
|
||||
};
|
||||
|
||||
void
|
||||
frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags)
|
||||
{
|
||||
vliw->next_slot = 0;
|
||||
vliw->constraint_violation = 0;
|
||||
vliw->mach = mach;
|
||||
vliw->elf_flags = elf_flags;
|
||||
|
||||
switch (mach)
|
||||
{
|
||||
case bfd_mach_fr400:
|
||||
vliw->current_vliw = fr400_allowed_vliw;
|
||||
vliw->unit_mapping = fr400_unit_mapping;
|
||||
break;
|
||||
default:
|
||||
vliw->current_vliw = fr500_allowed_vliw;
|
||||
vliw->unit_mapping = fr500_unit_mapping;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if unit1 is a match for unit2.
|
||||
Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the
|
||||
*_allowed_vliw tables above. */
|
||||
static int
|
||||
match_unit (FRV_VLIW *vliw,
|
||||
CGEN_ATTR_VALUE_TYPE unit1, CGEN_ATTR_VALUE_TYPE unit2)
|
||||
{
|
||||
/* Map any specialized implementation units to actual ones. */
|
||||
unit1 = vliw->unit_mapping[unit1];
|
||||
|
||||
if (unit1 == unit2)
|
||||
return 1;
|
||||
if (unit1 < unit2)
|
||||
return 0;
|
||||
|
||||
switch (unit1)
|
||||
{
|
||||
case UNIT_I01:
|
||||
case UNIT_FM01:
|
||||
case UNIT_B01:
|
||||
/* The 01 versions of these units are within 2 enums of the 0 or 1
|
||||
versions. */
|
||||
if (unit1 - unit2 <= 2)
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if the vliws match, 0 otherwise. */
|
||||
|
||||
static int
|
||||
match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vliw_size; ++i)
|
||||
{
|
||||
if ((*vliw1)[i] != (*vliw2)[i])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find the next vliw vliw in the table that can accomodate the new insn.
|
||||
If one is found then return it. Otherwise return NULL. */
|
||||
|
||||
static VLIW_COMBO *
|
||||
add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE unit)
|
||||
{
|
||||
int next = vliw->next_slot;
|
||||
VLIW_COMBO *current = vliw->current_vliw;
|
||||
VLIW_COMBO *potential;
|
||||
|
||||
if (next <= 0)
|
||||
abort (); /* Should never happen */
|
||||
|
||||
/* The table is sorted by units allowed within slots, so vliws with
|
||||
identical starting sequences are together. */
|
||||
potential = current;
|
||||
do
|
||||
{
|
||||
if (match_unit (vliw, unit, (*potential)[next]))
|
||||
return potential;
|
||||
++potential;
|
||||
}
|
||||
while (match_vliw (potential, current, next));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for the given major insn type in the given vliw. Return 1 if found,
|
||||
return 0 otherwise. */
|
||||
|
||||
static int
|
||||
find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vliw->next_slot; ++i)
|
||||
if (vliw->major[i] == major)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for constraints between the insns in the vliw due to major insn
|
||||
types. */
|
||||
|
||||
static int
|
||||
fr400_check_insn_major_constraints (
|
||||
FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
|
||||
)
|
||||
{
|
||||
/* In the cpu file, all media insns are represented as being allowed in
|
||||
both media units. This makes it easier since this is the case for fr500.
|
||||
Catch the invalid combinations here. Insns of major class FR400_MAJOR_M_2
|
||||
cannot coexist with any other media insn in a vliw. */
|
||||
switch (major)
|
||||
{
|
||||
case FR400_MAJOR_M_2:
|
||||
return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1)
|
||||
&& ! find_major_in_vliw (vliw, FR400_MAJOR_M_2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
fr500_check_insn_major_constraints (
|
||||
FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
|
||||
)
|
||||
{
|
||||
/* TODO: A table might be faster for some of the more complex instances
|
||||
here. */
|
||||
switch (major)
|
||||
{
|
||||
case FR500_MAJOR_I_1:
|
||||
case FR500_MAJOR_I_4:
|
||||
case FR500_MAJOR_I_5:
|
||||
case FR500_MAJOR_I_6:
|
||||
case FR500_MAJOR_B_1:
|
||||
case FR500_MAJOR_B_2:
|
||||
case FR500_MAJOR_B_3:
|
||||
case FR500_MAJOR_B_4:
|
||||
case FR500_MAJOR_B_5:
|
||||
case FR500_MAJOR_B_6:
|
||||
case FR500_MAJOR_F_4:
|
||||
case FR500_MAJOR_F_8:
|
||||
case FR500_MAJOR_M_8:
|
||||
return 1; /* OK */
|
||||
case FR500_MAJOR_I_2:
|
||||
/* Cannot coexist with I-3 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3);
|
||||
case FR500_MAJOR_I_3:
|
||||
/* Cannot coexist with I-2 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2);
|
||||
case FR500_MAJOR_F_1:
|
||||
case FR500_MAJOR_F_2:
|
||||
/* Cannot coexist with F-5, F-6, or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_F_3:
|
||||
/* Cannot coexist with F-7, or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_F_5:
|
||||
/* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_F_6:
|
||||
/* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_F_7:
|
||||
/* Cannot coexist with F-3, F-5, F-7, or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_M_1:
|
||||
/* Cannot coexist with M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_M_2:
|
||||
case FR500_MAJOR_M_3:
|
||||
/* Cannot coexist with M-5, M-6 or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_M_4:
|
||||
/* Cannot coexist with M-6 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6);
|
||||
case FR500_MAJOR_M_5:
|
||||
/* Cannot coexist with M-2, M-3, M-5, M-6 or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_M_6:
|
||||
/* Cannot coexist with M-2, M-3, M-4, M-5, M-6 or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_4)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
|
||||
case FR500_MAJOR_M_7:
|
||||
/* Cannot coexist with M-1, M-2, M-3, M-5, M-6 or M-7 insn. */
|
||||
return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_M_7)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
|
||||
&& ! find_major_in_vliw (vliw, FR500_MAJOR_F_7);
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
check_insn_major_constraints (
|
||||
FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
|
||||
)
|
||||
{
|
||||
int rc;
|
||||
switch (vliw->mach)
|
||||
{
|
||||
case bfd_mach_fr400:
|
||||
rc = fr400_check_insn_major_constraints (vliw, major);
|
||||
break;
|
||||
default:
|
||||
rc = fr500_check_insn_major_constraints (vliw, major);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Add in insn to the VLIW vliw if possible. Return 0 if successful,
|
||||
non-zero otherwise. */
|
||||
int
|
||||
frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn)
|
||||
{
|
||||
int index;
|
||||
CGEN_ATTR_VALUE_TYPE major;
|
||||
CGEN_ATTR_VALUE_TYPE unit;
|
||||
VLIW_COMBO *new_vliw;
|
||||
|
||||
if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn))
|
||||
return 1;
|
||||
|
||||
index = vliw->next_slot;
|
||||
if (index >= FRV_VLIW_SIZE)
|
||||
return 1;
|
||||
|
||||
unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
|
||||
if (unit == UNIT_NIL)
|
||||
abort (); /* no UNIT specified for this insn in frv.cpu */
|
||||
|
||||
if (vliw->mach == bfd_mach_fr400)
|
||||
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR);
|
||||
else
|
||||
major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR);
|
||||
|
||||
if (index <= 0)
|
||||
{
|
||||
/* Any insn can be added to slot 0. */
|
||||
while (! match_unit (vliw, unit, (*vliw->current_vliw)[0]))
|
||||
++vliw->current_vliw;
|
||||
vliw->major[0] = major;
|
||||
vliw->next_slot = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If there are already insns in the vliw(s) check to see that
|
||||
this one can be added. Do this by finding an allowable vliw
|
||||
combination that can accept the new insn. */
|
||||
if (! (vliw->elf_flags & EF_FRV_NOPACK))
|
||||
{
|
||||
new_vliw = add_next_to_vliw (vliw, unit);
|
||||
if (new_vliw && check_insn_major_constraints (vliw, major))
|
||||
{
|
||||
vliw->current_vliw = new_vliw;
|
||||
vliw->major[index] = major;
|
||||
vliw->next_slot++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The frv machine supports all packing conbinations. If we fail,
|
||||
to add the insn, then it could not be handled as if it was the fr500.
|
||||
Just return as if it was handled ok. */
|
||||
if (vliw->mach == bfd_mach_frv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vliw->constraint_violation = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
spr_valid (regno)
|
||||
long regno;
|
||||
{
|
||||
if (regno < 0) return 0;
|
||||
if (regno <= 4095) return 1;
|
||||
return 0;
|
||||
}
|
||||
/* -- */
|
||||
|
||||
/* -- asm.c */
|
||||
static const char * parse_ulo16
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
|
||||
static const char * parse_uslo16
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
|
||||
static const char * parse_uhi16
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
|
||||
static long parse_register_number
|
||||
PARAMS ((const char **));
|
||||
static const char * parse_spr
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
|
||||
static const char * parse_d12
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
|
||||
static const char * parse_s12
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
|
||||
static const char * parse_u12
|
||||
PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
|
||||
|
||||
static const char *
|
||||
parse_ulo16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
if (**strp == '#' || **strp == '%')
|
||||
{
|
||||
if (strncasecmp (*strp + 1, "lo(", 3) == 0)
|
||||
{
|
||||
*strp += 4;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing ')'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value >>= 16;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
}
|
||||
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_uslo16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
if (**strp == '#' || **strp == '%')
|
||||
{
|
||||
if (strncasecmp (*strp + 1, "lo(", 3) == 0)
|
||||
{
|
||||
*strp += 4;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing ')'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value &= 0xffff;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
}
|
||||
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_uhi16 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
if (**strp == '#' || **strp == '%')
|
||||
{
|
||||
if (strncasecmp (*strp + 1, "hi(", 3) == 0)
|
||||
{
|
||||
*strp += 4;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value >>= 16;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing ')'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
value >>= 16;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
}
|
||||
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
static long
|
||||
parse_register_number (strp)
|
||||
const char **strp;
|
||||
{
|
||||
int regno;
|
||||
if (**strp < '0' || **strp > '9')
|
||||
return -1; /* error */
|
||||
|
||||
regno = **strp - '0';
|
||||
for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
|
||||
regno = regno * 10 + (**strp - '0');
|
||||
|
||||
return regno;
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_spr (cd, strp, table, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
CGEN_KEYWORD * table;
|
||||
long *valuep;
|
||||
{
|
||||
const char *save_strp;
|
||||
long regno;
|
||||
|
||||
/* Check for spr index notation. */
|
||||
if (strncasecmp (*strp, "spr[", 4) == 0)
|
||||
{
|
||||
*strp += 4;
|
||||
regno = parse_register_number (strp);
|
||||
if (**strp != ']')
|
||||
return "missing `]'";
|
||||
++*strp;
|
||||
if (! spr_valid (regno))
|
||||
return "Special purpose register number is out of range";
|
||||
*valuep = regno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
save_strp = *strp;
|
||||
regno = parse_register_number (strp);
|
||||
if (regno != -1)
|
||||
{
|
||||
if (! spr_valid (regno))
|
||||
return "Special purpose register number is out of range";
|
||||
*valuep = regno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*strp = save_strp;
|
||||
return cgen_parse_keyword (cd, strp, table, valuep);
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_d12 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
/* Check for small data reference. */
|
||||
if (**strp == '#' || **strp == '%')
|
||||
{
|
||||
if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
}
|
||||
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_s12 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
/* Check for small data reference. */
|
||||
if ((**strp == '#' || **strp == '%')
|
||||
&& strncasecmp (*strp + 1, "gprel12(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (**strp == '#')
|
||||
++*strp;
|
||||
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_u12 (cd, strp, opindex, valuep)
|
||||
CGEN_CPU_DESC cd;
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long *valuep;
|
||||
{
|
||||
const char *errmsg;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
bfd_vma value;
|
||||
|
||||
/* Check for small data reference. */
|
||||
if ((**strp == '#' || **strp == '%')
|
||||
&& strncasecmp (*strp + 1, "gprel12(", 8) == 0)
|
||||
{
|
||||
*strp += 9;
|
||||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
|
||||
&result_type, &value);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (**strp == '#')
|
||||
++*strp;
|
||||
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- */
|
||||
|
||||
/* -- dis.c */
|
||||
static void print_spr
|
||||
PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned));
|
||||
static void print_hi
|
||||
PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
|
||||
static void print_lo
|
||||
PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
|
||||
|
||||
static void
|
||||
print_spr (cd, dis_info, names, regno, attrs)
|
||||
CGEN_CPU_DESC cd;
|
||||
PTR dis_info;
|
||||
CGEN_KEYWORD *names;
|
||||
long regno;
|
||||
unsigned int attrs;
|
||||
{
|
||||
/* Use the register index format for any unnamed registers. */
|
||||
if (cgen_keyword_lookup_value (names, regno) == NULL)
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) dis_info;
|
||||
(*info->fprintf_func) (info->stream, "spr[%ld]", regno);
|
||||
}
|
||||
else
|
||||
print_keyword (cd, dis_info, names, regno, attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
print_hi (cd, dis_info, value, attrs, pc, length)
|
||||
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
|
||||
PTR dis_info;
|
||||
long value;
|
||||
unsigned int attrs ATTRIBUTE_UNUSED;
|
||||
bfd_vma pc ATTRIBUTE_UNUSED;
|
||||
int length ATTRIBUTE_UNUSED;
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) dis_info;
|
||||
if (value)
|
||||
(*info->fprintf_func) (info->stream, "0x%lx", value);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "hi(0x%lx)", value);
|
||||
}
|
||||
|
||||
static void
|
||||
print_lo (cd, dis_info, value, attrs, pc, length)
|
||||
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
|
||||
PTR dis_info;
|
||||
long value;
|
||||
unsigned int attrs ATTRIBUTE_UNUSED;
|
||||
bfd_vma pc ATTRIBUTE_UNUSED;
|
||||
int length ATTRIBUTE_UNUSED;
|
||||
{
|
||||
disassemble_info *info = (disassemble_info *) dis_info;
|
||||
if (value)
|
||||
(*info->fprintf_func) (info->stream, "0x%lx", value);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "lo(0x%lx)", value);
|
||||
}
|
||||
|
||||
/* -- */
|
215
cpu/simplify.inc
Normal file
215
cpu/simplify.inc
Normal file
@ -0,0 +1,215 @@
|
||||
; Collection of macros, for GNU Binutils .cpu files. -*- Scheme -*-
|
||||
;
|
||||
; Copyright 2000 Free Software Foundation, Inc.
|
||||
;
|
||||
; Contributed by Red Hat Inc.
|
||||
;
|
||||
; This file is part of the GNU Binutils.
|
||||
;
|
||||
; This program is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program; if not, write to the Free Software
|
||||
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
; Enums.
|
||||
|
||||
; Define a normal enum without using name/value pairs.
|
||||
; This is currently the same as define-full-enum but it needn't remain
|
||||
; that way (it's define-full-enum that would change).
|
||||
|
||||
(define-pmacro (define-normal-enum name comment attrs prefix vals)
|
||||
"\
|
||||
Define a normal enum, fixed number of arguments.
|
||||
"
|
||||
(define-full-enum name comment attrs prefix vals)
|
||||
)
|
||||
|
||||
; Define a normal insn enum.
|
||||
|
||||
(define-pmacro (define-normal-insn-enum name comment attrs prefix fld vals)
|
||||
"\
|
||||
Define a normal instruction opcode enum.
|
||||
"
|
||||
(define-full-insn-enum name comment attrs prefix fld vals)
|
||||
)
|
||||
|
||||
; Instruction fields.
|
||||
|
||||
; Normally, fields are unsigned have no encode/decode needs.
|
||||
|
||||
(define-pmacro (define-normal-ifield name comment attrs start length)
|
||||
"Define a normal instruction field.\n"
|
||||
(define-full-ifield name comment attrs start length UINT #f #f)
|
||||
)
|
||||
|
||||
; For those who don't like typing.
|
||||
|
||||
(define-pmacro df
|
||||
"Shorthand form of define-full-ifield.\n"
|
||||
define-full-ifield
|
||||
)
|
||||
(define-pmacro dnf
|
||||
"Shorthand form of define-normal-ifield.\n"
|
||||
define-normal-ifield
|
||||
)
|
||||
|
||||
; Define a normal multi-ifield.
|
||||
; FIXME: The define-normal version for ifields doesn't include the mode.
|
||||
|
||||
(define-pmacro (define-normal-multi-ifield name comment attrs
|
||||
mode subflds insert extract)
|
||||
"Define a normal multi-part instruction field.\n"
|
||||
(define-full-multi-ifield name comment attrs mode subflds insert extract)
|
||||
)
|
||||
|
||||
; For those who don't like typing.
|
||||
|
||||
(define-pmacro dnmf
|
||||
"Shorthand form of define-normal-multi-ifield.\n"
|
||||
define-normal-multi-ifield
|
||||
)
|
||||
|
||||
; Simple multi-ifields: mode is UINT, default insert/extract support.
|
||||
|
||||
(define-pmacro (dsmf name comment attrs subflds)
|
||||
"Define a simple multi-part instruction field.\n"
|
||||
(define-full-multi-ifield name comment attrs UINT subflds #f #f)
|
||||
)
|
||||
|
||||
; Hardware.
|
||||
|
||||
; Simpler version for most hardware elements.
|
||||
; Allow special assembler support specification but no semantic-name or
|
||||
; get/set specs.
|
||||
|
||||
(define-pmacro (define-normal-hardware name comment attrs type
|
||||
indices values handlers)
|
||||
"\
|
||||
Define a normal hardware element.
|
||||
"
|
||||
(define-full-hardware name comment attrs name type
|
||||
indices values handlers () () ())
|
||||
)
|
||||
|
||||
; For those who don't like typing.
|
||||
|
||||
(define-pmacro dnh
|
||||
"Shorthand form of define-normal-hardware.\n"
|
||||
define-normal-hardware
|
||||
)
|
||||
|
||||
; Simpler version of dnh that leaves out the indices, values, handlers,
|
||||
; get, set, and layout specs.
|
||||
; This is useful for 1 bit registers.
|
||||
; ??? While dsh and dnh aren't that distinguishable when perusing a .cpu file,
|
||||
; they both take a fixed number of positional arguments, and dsh is a proper
|
||||
; subset of dnh with all arguments in the same positions, so methinks things
|
||||
; are ok.
|
||||
|
||||
(define-pmacro (define-simple-hardware name comment attrs type)
|
||||
"\
|
||||
Define a simple hardware element (usually a scalar register).
|
||||
"
|
||||
(define-full-hardware name comment attrs name type () () () () () ())
|
||||
)
|
||||
|
||||
(define-pmacro dsh
|
||||
"Shorthand form of define-simple-hardware.\n"
|
||||
define-simple-hardware
|
||||
)
|
||||
|
||||
; Operands.
|
||||
|
||||
(define-pmacro (define-normal-operand name comment attrs type index)
|
||||
"Define a normal operand.\n"
|
||||
(define-full-operand name comment attrs type DFLT index () () ())
|
||||
)
|
||||
|
||||
; For those who don't like typing.
|
||||
; FIXME: dno?
|
||||
|
||||
(define-pmacro dnop
|
||||
"Shorthand form of define-normal-operand.\n"
|
||||
define-normal-operand
|
||||
)
|
||||
|
||||
(define-pmacro (dndo x-name x-mode x-args
|
||||
x-syntax x-base-ifield x-encoding x-ifield-assertion
|
||||
x-getter x-setter)
|
||||
"Define a normal derived operand."
|
||||
(define-derived-operand
|
||||
(name x-name)
|
||||
(mode x-mode)
|
||||
(args x-args)
|
||||
(syntax x-syntax)
|
||||
(base-ifield x-base-ifield)
|
||||
(encoding x-encoding)
|
||||
(ifield-assertion x-ifield-assertion)
|
||||
(getter x-getter)
|
||||
(setter x-setter)
|
||||
)
|
||||
)
|
||||
|
||||
; Instructions.
|
||||
|
||||
; Define an instruction object, normal version.
|
||||
; At present all fields must be specified.
|
||||
; Fields ifield-assertion is absent.
|
||||
|
||||
(define-pmacro (define-normal-insn name comment attrs syntax fmt semantics timing)
|
||||
"Define a normal instruction.\n"
|
||||
(define-full-insn name comment attrs syntax fmt () semantics timing)
|
||||
)
|
||||
|
||||
; To reduce the amount of typing.
|
||||
; Note that this is the same name as the D'ni in MYST. Oooohhhh.....
|
||||
; this must be the right way to go. :-)
|
||||
|
||||
(define-pmacro dni
|
||||
"Shorthand form of define-normal-insn.\n"
|
||||
define-normal-insn
|
||||
)
|
||||
|
||||
; Macro instructions.
|
||||
|
||||
; Define a macro-insn object, normal version.
|
||||
; This only supports expanding to one real insn.
|
||||
|
||||
(define-pmacro (define-normal-macro-insn name comment attrs syntax expansion)
|
||||
"Define a normal macro instruction.\n"
|
||||
(define-full-minsn name comment attrs syntax expansion)
|
||||
)
|
||||
|
||||
; To reduce the amount of typing.
|
||||
|
||||
(define-pmacro dnmi
|
||||
"Shorthand form of define-normal-macro-insn.\n"
|
||||
define-normal-macro-insn
|
||||
)
|
||||
|
||||
; Modes.
|
||||
; ??? Not currently available for use.
|
||||
;
|
||||
; Define Normal Mode
|
||||
;
|
||||
;(define-pmacro (define-normal-mode name comment attrs bits bytes
|
||||
; non-mode-c-type printf-type sem-mode ptr-to host?)
|
||||
; "Define a normal mode.\n"
|
||||
; (define-full-mode name comment attrs bits bytes
|
||||
; non-mode-c-type printf-type sem-mode ptr-to host?)
|
||||
;)
|
||||
;
|
||||
; For those who don't like typing.
|
||||
;(define-pmacro dnm
|
||||
; "Shorthand form of define-normal-mode.\n"
|
||||
; define-normal-mode
|
||||
;)
|
Loading…
Reference in New Issue
Block a user