⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appendix b the salvm instruction set.htm

📁 英文版编译器设计:里面详细介绍啦C编译器的设计
💻 HTM
📖 第 1 页 / 共 4 页
字号:

      <B>Figure {EESORD}</B>  An example of pushing data onto the EES in the order
      that it appears in the equation.  
</PRE>Some of these instructions bear a little explanation. For instance, the 
modulus operator does not work correctly for all implementations. Modulus (or 
remainder) is mathematically defined such that <TT>(a/b)*b + a mod b = a</TT>, 
for <I>all</I> <TT>a</TT> and <TT>b</TT>. For some implementations of modulus, 
this holds true only when a and b are positive. This comes as a shortcomming of 
2's compliment arithmetic, and is the only real disadvantage of this 
representation. The SALVM uses the mathematical definition of modulus. Remember 
then, that modulus in the SALVM is a little slow.
<P>Although <TT>A MODx B</TT> finds the remainder of <TT>A DIVx B</TT>, the 
<TT>FMODx</TT> instruction is something a little different. For one thing, this 
instruction only works on one operand. If A is positive, <TT>FMODx A</TT> will 
return the portion of A between (1, 0]. If A is negative, it will return the 
portion of A within the interval [0, -1).
<P>The <TT>FTRNCx</TT> instruction works opposite the <TT>FTRNCx</TT> 
instruction. If A is positive, <TT>FTRNCx A</TT> will return the portion of A 
greater than or equal to 1. If A is negative, it will return the portion of A 
less than or equal to -1. Mathematically, <TT>FTRNC A + FMOD A = A.</TT>
<P>All of the other instructions should be familiar, and no further explanation 
should be required.
<P>
<H2>B.3 Increment and Decrement Instructions</H2><!-------------------------------------------------------------------------------->There 
is also a set of instructions for incrementing and decrementing a value on the 
EES. These instructions do not consume their operand, they merely increment or 
decrement. They are listed in table {INCDEC}
<P><PRE>        Data Type(s)        bits increment  decrement
      =================================================
         (un)signed byte    8    INCB       DECB
         (un)signed word    16   INCW       DECW
         (un)signed dword   32   INCD       DECD
         (un)signed qword   64   INCQ       DECQ
         single precision   32   FINCS      FDECS
         double precision   64   FINCD      FDECD
         tenbyte precision  80   FINCT      FDECT
         quad precision     128  FINCQ      FDECQ

      <B>Table {INCDEC}</B>  This table shows all of the increment and decrement
      instructions.
</PRE>As an example, <TT>FDECD</TT> will take the top 8 bytes on the EES, treat 
it as a double precision float, and increment it, leaving the result on the EES. 
See figure {INCDECF} <PRE>
      |  3.5  |               |  4.5  |
      |       | --&gt; FINCx --&gt; |       |
      |  ...  |               |  ...  |
      |_______|               |_______|
         EES                     EES
        Before                  After

      <B>Figure {INCDECF}</B>  A representation of the way the increment and 
      decrement instructions work.
</PRE>
<H2>B.4 Bit Operation Instructions</H2><!-------------------------------------------------------------------------------->The 
bitwise instructions within the VM are organized into two groups. All groups 
work on data sizes ranging from 8 to 64 bits. The first group performs the four 
logical operations: and, or, exclusive or, and not. The second group performs 
bit shifts (signed and unsigned), and bit rotations. <PRE>                                                                     Signed
                                                        Shift Shift  Shift  Rotate Rotate
        Data Type(s)        bits And   Or   Xor   Not   Left  Right  Right  Left   Right
      =====================================================================================
         (un)signed byte    8    ANDB  ORB  XORB  NOTB  SHLB  USHRB  SSHRB  ROLB   RORB
         (un)signed word    16   ANDW  ORW  XORW  NOTW  SHLW  USHRW  SSHRW  ROLW   RORW
         (un)signed dword   32   ANDD  ORD  XORD  NOTD  SHLD  USHRD  SSHRD  ROLD   RORD
         (un)signed qword   64   ANDQ  ORQ  XORQ  NOTQ  SHLQ  USHRQ  SSHRQ  ROLQ   RORQ

      <B>Table {SHFROT}</B>  The bit shift and rotate instructions.
</PRE>These instructions all work the same way that the arithmetic instructions 
work. Remember that the operands must be pushed in the order that they appear. 
The <TT>NOTx</TT> instruction takes only one operand. All of the others take 
two. For example, the <TT>ANDW</TT> will take two words from the EES, and them 
together, and store the result on the EES as a word.
<P>The shift and rotate instructions are a little different in that they only 
require one byte to designate the distance to shift. These will take a byte from 
the top of the EES, and shift/rotate the underlying quantity of bytes. For 
instance, <TT>ROLQ</TT> will take a byte and a quadword from the EES (the byte 
is on the top and the qword underneath), left-rotate the quadword by the number 
in the byte, then store the rotated quadword on the EES. <PRE>
      |     [byte]|                |[-shifted--|
      |[-quadword-|                |-quadword-]|
      |----------]|  --&gt; ROLQ --&gt;  |           |
      |           |                |           |
      |    ...    |                |    ...    |
      |___________|                |___________|
           EES                          EES
         Before                        After

      <B>Figure {SREXMP}</B>  An example of how the shift and rotate instructions
      work.
</PRE>
<H2>B.5 Conversion Instructions</H2><!-------------------------------------------------------------------------------->The 
reader has probebly noticed so far that all instructions work on one and only 
one type of data. This is true. Since this is the case, the need for data 
conversion arises. The SALVM has instructions for just this task. There are two 
types of conversion instructions. The first type converts between levels of 
precision, like from a byte to a word, or from a single precision to a double 
precision. The second type converts from one data type to another, like integer 
to real. Among both groups, there exist a couple or so instructions, which are 
for conversions that are very commonly performed.
<P>
<H3>B.5.1 Precision Conversion</H3><!-------------------------------------------------------------------------------->Precision 
conversion is a very common task in most languages. The precision conversion 
instructions take one operand on the EES, and one immediate byte as a parameter 
that tells what type of conversion is to be performed. See table {CONV}. <PRE>        Op-Code  Meaning
      ============================================
        UCNV     Convert an unsigned integer
        SCNV     Convert a signed integer
        FCNV     Convert a floating point number

      <B>Table {CONV}</B>  The conversion op-codes.
</PRE>These instructions have no direct way of telling what quantity to start 
out with, and what quantity to emd up with, so they require an immediate 
parameter. The parameter is a single byte, where the most significant nibble 
designates the quantity of bytes to start with, and the least significant nibble 
designates the quantity of bytes to convert to. The values of each nibble and 
the type represented are listed in table {NIBVAL}.
<P><PRE>        Nibble
        Value   Size represented
      ==================================
        0       card8
        1       card16
        2       card32
        3       card64

        4       int8
        5       int16
        6       int32
        7       int64

        8       real32
        9       real64
        A       real80
        B       real128

      <B>Table {NIBVAL}</B>  Values of each nibble for precision conversion.
</PRE>You might notice that the first five values represent <TT>2^n</TT> bytes. 
The last one was given an arbitrary value, since for <TT>2^n = 10</TT>, n is not 
an integer.
<P>As an example, to convert a single precision float to a quad precision float, 
the instruction would be formatted like figure {PCFORM}. <PRE>      -------------------------
       ... | FCNV |  8B  | ...
      -------------------------

      <B>Figure {PCFORM}</B>  Example to convert a single precision float on the
      EES to a quad precision float.
</PRE>All of the precision conversion instructions in table {CONV} work in this 
manner.
<P>In addition to these three instructions, there are a handful of instructions, 
which are optimized versions of the above. These instructions represent the most 
common conversions that are encountered. They are listed in table {COMCNV}. <PRE>        Intruction  Meaning
      ===========================================
        BTOD        byte to dword
        DTOB        dword to byte
        WTOD        word to dword
        DTOW        dword to word
        FSTOFD      single precision to double precision
        FDTOFS      double precision to single precision

      <B>Table {COMCNV}</B>  These are the most common conversions.
</PRE>These conversions are most common because they involve conversions to and 
from the default types in SAL. In SAL, an <TT>int</TT> defaults to 32 bits, and 
a <TT>real</TT> defaults to double precision.
<P>These instructions take no immediate parameters, and each one was crafted to 
perform explicitly one type of conversion.
<P>Notice that whenever converting data from a higher level of precision to a 
lower level of precision, there is a possible loss of data.
<P>
<H3>B.5.2 Data Type Conversion</H3><!-------------------------------------------------------------------------------->Data 
type conversion involves a slightly different kind of conversion, e.g., 
conversion from int to real, or vice versa. Here they are in table {TCONV} <PRE>        Op-Code  Meaning
      ============================================
        STOF     Signed integer to float
        FTOS     Float to signed integer
        UTOF     Unsigned integer to float
        FTOU     Float to unsigned integer

      <B>Table {TCONV}</B>  The data conversion instructions.
</PRE>These instructions function in a similar manner as the ones for precision 
conversion. They all take a byte that describes the precision to convert from 
and the precision to convert to. See table {NIBVAL}. Let's say we want to 
convert a signed word to a double precision value (real64). We would format the 
instruction as shown in figure {DCFORM} <PRE>      -----------------------
       ... | STOF | 59 | ... 
      -----------------------

      <B>Figure {DCFORM}</B>  Example converting a word to a double precision 
      value.
</PRE>Like the precision conversion op-codes, the data type conversion op-codes 
have some optimized siblings. These are listed in table {COMTCNV} <PRE>        Intruction  Meaning
      ===========================================
        DTOFD       Signed dword to double precision real
        FDTOD       Double precision real to signed dword

      <B>Table {COMCNV}</B>  These are the most common conversions.
</PRE>Since we are using a 2's compliment architecture, it would not make a lot 
of sense for there to be instructions that convert between signed and unsigned 
integers. Also, notice that only positive real numbers will correctly convert to 
an unsigned integer. In that case, the sign gets truncated.
<P>
<H2>B.6 Bit Comparison Instructions</H2><!-------------------------------------------------------------------------------->The 
comparison instructions for the VM return a byte containing either a 0 or a 1 
depending upon whether or not the comparison was true. They are listed in table 
{COMPINS}. <PRE>         Data 
         size    =     &lt;&gt;    &gt;     &lt;     &gt;=    &lt;=
      ===============================================
         byte    EQLB  NEQB  GTRB  LESB  GEQB  LEQB
         word    EQLW  NEQW  GTRW  LESW  GEQW  LEQW
         dword   EQLD  NEQD  GTRD  LESD  GEQD  LEQD
         qword   EQLQ  NEQQ  GTRQ  LESQ  GEQQ  LEQQ

      <B>Table {COMPINS}</B>  The comparison instructions.
</PRE>These instructions actually work in two steps. The first step is to 
compare the two quantities of data, and the second is to evaluate the comparison 
to see if the result was true.
<P>The method of comparison assumes a 2's compliment host architecture. The 
comparison of A to B is done by subtracting B from A (A-B). Using this 
technique, it becomes irrelevant whether the integer is signed or unsigned. This 
is one of the beauties of 2's compliment. Also, floating point numbers can be 
compared in the same way, since their format is such that their relationship can 
be easily determined without using special operations. That is, if A and B are 
floating point numbers, and A is less than B, the binary representation of A and 
B will be such that A is less than B for all A and B. The same holds for all 
relations with real numbers. In short, what we have is a method for comparing 
quantities of data without reguard to their format, whatsoever. To compare A to 
B, all we need is for A to be the same size and type as B, and we subtract B 
from A, and the result is a signed integer, where a result that is less than 0 
means A is less than B, a result that is greater than zero means that A is 
greater than B, and a result that is equal to zero means that A is equal to B.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -