next up previous contents
Next: Target-Specific Functionalities Up: SALTO Target Description Specifications Previous: Lexical Structure of the

Instruction Sets

 

The description of the instruction set is made by providing individual descriptions of assembler-supported instruction/operation mnemonics and macros. Each instruction/operation description contains the name of the mnemonic, the meta-variable pattern identifying its operands, the reservation table information, and possibly, semantical information (presence of delays introduced by the instruction, etc.).

VLIW Instruction Width

The number of operations in a VLIW instruction (the maximum number of operations that can be issued in a single clock cycle) is defined using the expression

< inst_width>::=

 ( inst_width <size>) 

where <size> is an integer. If this definition is omitted, the default value of 1 is assumed.

Semantical Information

 

Semantical information supported by SALTO covers the specification of operands of control flow instructions, and the definitions of load, write, and branch delays (and the associated limitations on instruction scheduling).

In its most general form, the semantical information follows syntax

< semantical_info>::=

 ( sem
[<semantical_property>+])  

< semantical_property>::=

  
	<control_target> |
	(return) |
	<delay_slot> |
	(noreorder)

Basic semantical information on branch, jump and call instructions uses a common format

< control_target>::=

 ( <control_flow_insn>
  <num_arg>)  

where
  • <control_flow_insn> is either branch, jump, or call, depending on whether the instruction concerned is a conditional branch, an (unconditional) jump, or a subroutine call;
  • <num_arg> is the position of the target address in the parameter list of the instruction, counted from zero; if the target is not known at compile time (i.e., indirect addressing is being used), the value of <num_arg> is -1.

The expression (return) indicates the return to an implicit address.

Delay slot information is provided using the delay_slot expression:

< delay_slot>::=

 ( delay_slot

<slot>)


where
  • <slot> is the integer representing the branch delay, i.e., the number of instructions issued before the execution resumes at the new address.

The restrictions on instruction reordering introduced by the presence of delay slots are expressed using the (noreorder) property. If present, (noreorder) forbids the instructions preceding the current instruction to be rescheduled after it, and the instructions following it to be rescheduled before it. This restriction applies to instructions which terminate or are issued within the branch delay after the issue of the relevant control instruction.

Given the large variety and complexity of write-back by-pass definitions, by-pass facilities are expressed through a user-supplied hook function updateDelay(...) which produces updated instruction-to-instruction delay values on demand. In particular, this function (if available) is automatically called during the computation of minimum scheduling delay between instructions (see methods int INST::getDelay() and int INST::getResDelay() in section 3.3.5.)

Native Instructions

The general form of an instruction/operation definition is

< def_asm>::=

 ( def_asm
 "<name>"
 [ 
   (input "<format>")
   <res_table>
   <semantical_info>0|1
   (info "<any-text>")0|1  
    ])  


where
  • <name> is the mnemonic of the instruction/operation;
  • <format> is a string representing the format of instruction operands; <format> consists only of terminal symbols defined using def_exact and def_separ expressions and of meta-variables defined using def_token;
  • <res_table> is an expression describing the reservation table of the instruction or operation, either directly, or via a cpp macro-definition created using a #define directive;
  • <semantical_info> describes the scheduling constraints introduced by the instruction/operation;
  • the info field can contain any text. This field is used to attach an arbitrary textual information to an assembly instruction definition, and is not interpreted by SALTO. The text can be extracted at run time by calling method INST::getAsmInfo() on the instructions of the program (see section 3.3.5.)

Notes:

Example:

(def_asm  "fadd"            ; floating-point addition
   [(input  "g,m,s,t,d")    ; d <- s+t, plus guard (g) and modifier (m)
    R_FLOAT_ALU             ; reservation table of FP arithmetic
   ])
(def_asm  "jmpi"            ; jump to immediate address
   [(input  "g,m")          ; if (LSbit(g) == 1) then PC <- m
    R_BRANCH                ; reservation table of branching insns
    (sem  [ BRANCH(1)       ; "m" is the immediate address operand
            (delay_slot 3)  ; branch delay is 3
            (noreorder)     ; prevent insn reordering
          ])
   ])

Macro-Instructions

Macro-instructions of the assembly language are described in two steps:

The first definition uses the def_macro expression. Its syntax is close to that of a native instruction description, except that the semantical information section is replaced with the expansion of the macro-instruction into native instructions:

< def_macro>::=

 ( def_macro
 "<name>"
[ 
 (input "<format>")
 (info "<any-text>")0|1
 <macro_expansion>  
    ])  

where
  • <name> is the mnemonic of the macro-instruction;
  • <format> is a string representing the format of instruction operands; <format> consists only of terminal symbols defined using def_exact and of meta-variables defined using def_token; it is assumed that all operands follow the mnemonic and that only single-character separators are used between operands;
  • <macro_expansion> is an expansion of the macro-instruction into native instructions, described using an expand construct (defined below);
  • the info field can contain any text. This field is used to attach an arbitrary textual information to an assembly instruction definition, and is not interpreted by Salto. The text can be extracted at run time by calling method INST::getAsmInfo() on the instructions of the program (see section 3.3.5.)

Example:

; MIPS branch to immediate offset if greater or equal
(def_macro  "bge"
   [ (input  "s,t,i"  ) ; if (s>=t) then PC <- PC + i
     EXPAND_BGE_1       ; expansion: EXPAND_BGE_1
   ])

Notes: are expanded during the parsing of the input program.

The expansion of macro-instructions is described using expand expressions which define the expansion of the macro into native instructions. Each native instruction in the expansion is described by its name, its input format, and a vector of operand construction directives.

For each meta-variable (formal parameter) in the input format of each native instruction in the expansion of the macro, there is a matching element in the vector operand construction vector. Each such field describes the way the corresponding actual parameter is built from the actual parameters of the macro and from predefined elements.

The expressions that can appear in the operand construction vector are divided in two groups: three basic forms, and three compound expressions that use the basic forms:

The syntax of the definitions of macro-instruction expansions is

< macro_expansion>::=

 ( expand
  [ 
    (build_asm
      "<ins_name>" "<ins_format>"
      [ 
        (with_reg "<reg>")*
        <positional_param>*
        (const_expr "<expr>")*
        (multireg
	    <base_register> <index> <size>
  )*
        (add_expr
            <positional_param>
            (const_expr "<expr>")  
  )*
        (imm_part
            "<part>" "<sign>" <width>
            <positional_param>  
  )*
    ]  
  )+  
    ])  

< base_register>::=

 <positional_param> | (with_reg "<reg>")


where
  • <ins_name> is the name of the macro-instruction;
  • <ins_format> is the string describing the format of the operands of the macro-instruction; the string "*" indicates that the appropriate format should be determined at run-time;
  • the expression (with_reg <reg>) indicates that the register reg should explicitly be used when expanding this macro-instruction;
  • <expr> is an arithmetical expression evaluating to a constant, such as "7*4";
  • <index> is a (possibly negative) integer used to compute the name of the first register of a multi-register (an aggregate register spanning several hardware registers and used as a single operand) from the register designated by <base_register>;
  • <size> is an integer describing the width, in hardware registers, of the multi-register data set;
  • <part> is either upper or lower;
  • <sign> is either signed or unsigned; signed indicates that the value extracted should be sign extended to the width expected by the destination resource
  • <width> is an integer indicating the size, in bits, of the subset to extract.

Example:

The following example shows the expansion of a branching macro ``bge'' (``branch if greater or equal'') used by MIPS assemblers:

; replaces "bge s,t,i" by the sequence :
; $at <- (s < t) ? 1 : 0
; if ($at == 0) then PC <- PC + i
#define M_BGE_1\
  (expand [\
          (build_asm "slt" "d,s,t" \
                     [(with_reg "$at") \
                      (match_arg 0) \
                      (match_arg 1)])\
          (build_asm "beq" "s,t,i" \
                     [(with_reg "$at") \
                      (with_reg "$0") \
                      (match_arg 2)]) \
          ])


next up previous contents
Next: Target-Specific Functionalities Up: SALTO Target Description Specifications Previous: Lexical Structure of the

Erven Rohou
Fri Oct 17 09:15:29 MET DST 1997