@@ -61,28 +61,41 @@ The `s` prefix denotes a signed operation while `u` denotes an unsigned operatio
6161 syntax Bool ::= Word ">=uWord" Word [function, total]
6262 rule W(I1) >=uWord W(I2) => I1 >=Int I2
6363```
64+ To avoid syntax conflicts, we define the following syntax with ` left ` associativity and clear precedence over the bitwise operations.
65+ ``` k
66+ syntax Word ::= left:
67+ Word "*Word" Word [function, total, symbol(mulWord)]
68+ | Word "*hWord" Word [function, total, symbol(mulhWord)]
69+ | Word "*huWord" Word [function, total, symbol(mulhuWord)]
70+ | Word "*hsuWord" Word [function, total, symbol(mulhsuWord)]
71+ > left:
72+ Word "+Word" Word [function, total, symbol(addWord)]
73+ | Word "-Word" Word [function, total, symbol(subWord)]
74+ > left:
75+ Word ">>lWord" Word [function, total, symbol(rshWord)]
76+ | Word ">>aWord" Word [function, total, symbol(ashWord)]
77+ | Word "<<Word" Word [function, total, symbol(lshWord)]
78+ > left:
79+ Word "&Word" Word [function, total, symbol(andWord)]
80+ > left:
81+ Word "xorWord" Word [function, total, symbol(xorWord)]
82+ > left:
83+ Word "|Word" Word [function, total, symbol(orWord)]
84+ ```
85+
6486Note that two's complement enables us to use a single addition or subtraction operation for both signed and unsigned values.
6587``` k
66- syntax Word ::= Word "+Word" Word [function, total]
6788 rule W(I1) +Word W(I2) => chop(I1 +Int I2)
68-
69- syntax Word ::= Word "-Word" Word [function, total]
7089 rule W(I1) -Word W(I2) => chop(I1 -Int I2)
7190```
7291The same is true for the ` XLEN ` least-significant bits of the result of multiplication.
7392``` k
74- syntax Word ::= Word "*Word" Word [function, total, symbol(mulWord)]
7593 rule W(I1) *Word W(I2) => chop(I1 *Int I2)
7694```
7795The value of the upper ` XLEN ` bits however depends on signedness of the operands, as reflected by the followig functions.
7896``` k
79- syntax Word ::= Word "*hWord" Word [function, total, symbol(mulhWord)]
8097 rule W1 *hWord W2 => chop((Word2SInt(W1) *Int Word2SInt(W2)) >>Int XLEN)
81-
82- syntax Word ::= Word "*huWord" Word [function, total, symbol(mulhuWord)]
8398 rule W(I1) *huWord W(I2) => chop((I1 *Int I2) >>Int XLEN)
84-
85- syntax Word ::= Word "*hsuWord" Word [function, total, symbol(mulhsuWord)]
8699 rule W1 *hsuWord W(I2) => chop((Word2SInt(W1) *Int I2) >>Int XLEN)
87100```
88101Above, the ` chop ` utility function
@@ -92,18 +105,14 @@ Above, the `chop` utility function
92105```
93106is used to zero-out all but the least-significant ` XLEN ` -bits in case of overflow.
94107``` k
95- syntax Word ::= Word "&Word" Word [function, total]
96108 rule W(I1) &Word W(I2) => W(I1 &Int I2)
97109
98- syntax Word ::= Word "|Word" Word [function, total]
99110 rule W(I1) |Word W(I2) => W(I1 |Int I2)
100111
101- syntax Word ::= Word "xorWord" Word [function, total]
102112 rule W(I1) xorWord W(I2) => W(I1 xorInt I2)
103113
104- syntax Word ::= Word "<<Word" Int [function, total]
105- rule W(I1) <<Word I2 => chop(I1 <<Int I2) requires 0 <=Int I2
106- rule _ <<Word I2 => W(0) requires I2 <Int 0
114+ rule W(I1) <<Word W(I2) => chop(I1 <<Int I2) requires 0 <=Int I2
115+ rule _ <<Word W(I2) => W(0) requires I2 <Int 0
107116```
108117For right shifts, we provide both arithmetic and logical variants.
109118
@@ -114,14 +123,12 @@ Counterintuitively, we use the arithmetic right shift operator `>>Int` for `Int`
114123
115124That is, for any ` I:Int ` underlying some ` W(I):Word ` , applying ` >>Int ` will always pad with ` 0 ` s, correctly implementing a logical right shift.
116125``` k
117- syntax Word ::= Word ">>lWord" Int [function, total]
118- rule W(I1) >>lWord I2 => W(I1 >>Int I2) requires 0 <=Int I2
119- rule _ >>lWord I2 => W(0) requires I2 <Int 0
126+ rule W(I1) >>lWord W(I2) => W(I1 >>Int I2) requires 0 <=Int I2
127+ rule _ >>lWord W(I2) => W(0) requires I2 <Int 0
120128```
121129To actually perform an arithmetic shift over ` Word ` , we first convert to an infinitely sign-extended ` Int ` of equal value using ` Word2SInt ` , ensuring ` >>Int ` will pad with ` 1 ` s for a negative ` Word ` . The final result will still be infinitely sign-extended, so we must ` chop ` it back to a ` Word ` .
122130``` k
123- syntax Word ::= Word ">>aWord" Int [function, total]
124- rule W1 >>aWord I2 => chop(Word2SInt(W1) >>Int I2) requires 0 <=Int I2
125- rule _ >>aWord I2 => W(0) requires I2 <Int 0
131+ rule W1 >>aWord W(I2) => chop(Word2SInt(W1) >>Int I2) requires 0 <=Int I2
132+ rule _ >>aWord W(I2) => W(0) requires I2 <Int 0
126133endmodule
127134```
0 commit comments