3a_asm: adding some libraries, in order to be compatible with the tilab environment
[calu.git] / 3a_asm / PPC64.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Module      :  Text.Assembler.PPC64
4 -- Copyright   : (c) Jeff Douglas
5 -- License     :  BSD3
6 --
7 -- Maintainer  : Jeff Douglas
8 -- Stability   : experimental
9 -- Portability : portable
10 --
11 -- |
12 --
13 -----------------------------------------------------------------------------
14
15 module PPC64 (instruction,parseInstructions) where
16
17 import Prelude hiding (and,or)
18
19 import Data.Bits hiding (xor)
20 import qualified Data.Map as Map
21 import Data.Word
22 import Text.Parsec
23 import Text.Parsec.String
24 import Text.Parsec.Combinator
25 import Control.Monad
26 import Control.Applicative hiding ((<|>))
27
28 parseInstructions = many1 instruction
29
30 -- parsing --
31 instruction :: Parser Word32
32 instruction = foldl1 (<|>) (fmap try instructions) <* char '\n'
33
34 instructions = [
35   b,ba,b,bla,bc,bca,bcl,bcla,bclr ,bclrl ,bcctr ,bcctrl ,
36   sc ,
37   crand ,cror ,crxor ,crnand ,crnor ,creqv ,crandc ,crorc ,
38   mcrf ,
39   lbz,lbzx,lbzu,lbzux,lhz,lhzx,lhzu,lhzux,lha,lhax,lhau,lhaux,lwz,lwzx,lwzu,lwzux,lwa,lwax,lwaux,ld,ldx,ldu,ldux,
40   stb ,stbx ,stbu ,stbux ,sth ,sthx ,sthu ,sthux ,stw ,stwx ,stwu ,stwux ,std ,stdx ,stdu ,stdux ,
41   lhbrx ,lwbrx ,sthbrx ,stwbrx ,
42   lmw,stmw,
43   lswi ,lswx ,stswi ,stswx ,
44   addi,addis,add,add_,addo,addo_,subf,subf_,subfo,subfo_,addic,addic_,subfic,addc,addc_,addco,addco_,subfc,subfc_,subfco,
45   subfco_,adde,adde_,addeo,addeo_,subfe,subfe_,subfeo,subfeo_,addme,addme_,addmeo,addmeo_,subfme,subfme_,
46   subfmeo,subfmeo_,addze,addze_,addzeo,addzeo_,subfze,subfze_,subfzeo,subfzeo_,neg,neg_,nego,nego_,mulli,mulld,
47   mulld_,mulldo,mulldo_,mullw,mullw_,mullwo,mullwo_,mulhd,mulhd_,mulhw,mulhw_,mulhdu,mulhdu_,mulhwu,
48   mulhwu_,divd,divd_,divdo,divdo_,divw,divw_,divwo,divwo_,divdu,divdu_,divduo,divduo_,divwu,divwu_,divwuo,divwuo_,
49   cmpi,cmp,cmpli,cmpl,
50   tdi,twi,td,tw,
51   andi_ ,andis_ ,ori ,oris ,xori ,xors ,and ,and_ ,or ,or_ ,xor ,xor_ ,nand ,nand_ ,nor ,nor_ ,eqv ,eqv_ ,andc ,andc_ ,orc ,orc_ ,extsb ,extsb_ ,extsh ,extsh_ ,extsw ,extsw_ ,cntlzd ,cntlzd_ ,popcntb ,cntlzw ,cntlzw_ ,
52   rldicl  ,rldicl_ ,rldicr  ,rldicr_ ,rldic  ,rldic_ ,rlwinm  ,rlwinm_ ,rldcl  ,rldcl_ ,rldcr  ,rldcr_ ,rlwnm  ,rlwnm_ ,rldimi  ,rldimi_ ,rlwimi  ,rlwimi_ ,
53   sld  ,sld_ ,slw  ,slw_ ,srd  ,srd_ ,srw  ,srw_ ,sradi  ,sradi_ ,srawi  ,srawi_ ,srad ,srad_ ,sraw ,sraw_ ,
54   mtspr ,mfspr ,mtcrf ,
55   lfs
56   ]
57
58 comma = char ','
59 mnem m = string m >> space
60
61 iLit :: Parser Word32
62 iLit = liftM read (many1 digit)
63
64 (<.>) p n = p<*comma<*>n
65 (<@>) p n = p<*char '('<*>n<*char ')'
66 infixl 1 <.>
67 infixl 1 <@>
68
69 -- branch instructions
70 b = ins "b" v1 $ iform 18 0 0
71 ba = ins "ba" v1 $ iform 18 1 0
72 bl = ins "bl" v1 $ iform 18 0 1
73 bla = ins "bla" v1 $ iform 18 1 1
74
75 bc = ins "bc" csv3 $ bform 16 0 0
76 bca = ins "bca" csv3 $ bform 16 1 0
77 bcl = ins "bcl" csv3 $ bform 16 0 1
78 bcla = ins "bcla" csv3 $ bform 16 1 1
79
80 bclr = ins "bclr" csv3 $ xlform'b 19 16 0
81 bclrl = ins "bclrl" csv3 $ xlform'b 19 16 1
82
83 bcctr = ins "bcctr" csv3 $ xlform'b 19 528 0
84 bcctrl = ins "bcctrl" csv3 $ xlform'b 19 528 1
85
86 -- system call instruction
87 sc = ins "sc" v1 $ scform 17
88
89 -- condition register logical instructions
90 crand = ins "crand" csv3 $ xlform'a 19 257
91 cror = ins "cror" csv3 $ xlform'a 19 449
92 crxor = ins "cxor" csv3 $ xlform'a 19 193
93 crnand = ins "crnand" csv3 $ xlform'a 19 225
94 crnor = ins "crnor" csv3 $ xlform'a 19 33
95 creqv = ins "creqv" csv3 $ xlform'a 19 289
96 crandc = ins "crandc" csv3 $ xlform'a 19 129
97 crorc = ins "crorc" csv3 $ xlform'a 19 417
98
99 -- condition register field instruction
100 mcrf = ins "mcrf" csv2 $ xlform'c 19 0
101
102 -- fixed point load instructions
103 lbz = ins "lbz" csv3 $ dform'a 34
104 lbzx = ins "lbzx" csv3 $ xform'a 31 87
105 lbzu = ins "lbzu" csv3 $ dform'a 35
106 lbzux = ins "lbzux" csv3 $ xform'a 31 119
107 lhz = ins "lhz" csv3 $ dform'a 40
108 lhzx = ins "lhz" csv3 $ xform'a 31 279
109 lhzu = ins "lhzu" csv3 $ dform'a 41
110 lhzux = ins "lhzux" csv3 $ xform'a 31 311
111 lha = ins "lha" csv3 $ dform'a 42
112 lhax = ins "lhax" csv3 $ xform'a 31 343
113 lhau = ins "lhau" csv3 $ dform'a 43
114 lhaux = ins "lhaux" csv3 $ xform'a 31 375
115 lwz = ins "lwz" csv3 $ dform'a 32
116 lwzx = ins "lwzx" csv3 $ xform'a 31 23
117 lwzu = ins "lwzu" csv3 $ dform'a 33
118 lwzux = ins "lwzux" csv3 $ xform'a 31 55
119 lwa = ins "lwa" csv3 $ dsform 58 2
120 lwax = ins "lwax" csv3 $ xform'a  31 341
121 lwaux = ins "lwaux" csv3 $ xform'a 31 373
122 ld = ins "ld" csv3 $ dsform 58 151
123 ldx = ins "ldx" csv3 $ xform'a 31 21
124 ldu = ins "ldu" csv3 $ dsform 58 1
125 ldux = ins "ldux" csv3 $ xform'a 31 53
126
127 -- fixed point store instructions
128 stb = ins "stb" csv3 $ dform'a 38
129 stbx = ins "stbx" csv3 $ xform'a 31 215
130 stbu = ins "stbu" csv3 $ dform'a 39
131 stbux = ins "stbux" csv3 $ xform'a 31 247
132 sth = ins "sth" csv3 $ dform'a 44
133 sthx = ins "sthx" csv3 $ xform'a 31 407
134 sthu = ins "sthu" csv3 $ dform'a 45
135 sthux = ins "sthux" csv3 $ xform'a 31 439
136 stw = ins "stw" csv3 $ dform'a 36
137 stwx = ins "stwx" csv3 $ xform'a 31 151
138 stwu = ins "stwu" csv3 $ dform'a 37
139 stwux = ins "stwux" csv3 $ xform'a 31 183
140 std = ins "std" csv3 $ dsform 62 0
141 stdx = ins "stdx" csv3 $ xform'a 31 149
142 stdu = ins "stdu" csv3 $ dsform 37 1
143 stdux = ins "stdux" csv3 $ xform'a 31 181
144
145 -- fixed-point load and store with byte reversal instructions
146 lhbrx = ins "lhbrx" csv3 $ xform'a 31 790
147 lwbrx = ins "lwbrx" csv3 $ xform'a 31 534
148 sthbrx = ins "sthbrx" csv3 $ xform'a 31 918
149 stwbrx = ins "stwbrx" csv3 $ xform'a 31 662
150
151 -- fixed point load and store multiple instructions
152 lmw = ins "lmw" csv3 $ dform'a 46
153 stmw = ins "stmw" csv3 $ dform'a 47
154
155 -- fixed point move assist instructions
156 lswi = ins "lswi" csv3 $ xform'a 31 597
157 lswx = ins "lswx" csv3 $ xform'a 31 533
158 stswi = ins "stswi" csv3 $ xform'a 31 725
159 stswx = ins "stswx" csv3 $ xform'a 31 661
160
161 --fixed point arithmetic instructions
162 addi = ins "addi" csv3 $ dform'a 14
163 addis = ins "addis" csv3 $ dform'a 15
164
165 add = ins "add" csv3 $ xoform 31 266 0 0
166 add_ = ins "add." csv3 $ xoform 31 266 0 1
167 addo = ins "addo" csv3 $ xoform 31 266 1 0
168 addo_ = ins "addo." csv3 $ xoform 31 266 1 1
169 subf = ins "subf" csv3 $ xoform 31 40 0 0
170 subf_ = ins "subf." csv3 $ xoform 31 40 0 1
171 subfo = ins "subfo" csv3 $ xoform 31 40 1 0
172 subfo_ = ins "subfo." csv3 $ xoform 31 40 1 1
173
174 addic = ins "addic" csv3 $ dform'a 12
175 addic_ = ins "addic." csv3 $ dform'a 13
176 subfic = ins "subfic" csv3 $ dform'a 8
177
178 addc = ins "addc" csv3 $ xoform 31 10 0 0
179 addc_ = ins "addc." csv3 $ xoform 31 10 0 1
180 addco = ins "addco" csv3 $ xoform 31 10 1 0
181 addco_ = ins "addco." csv3 $ xoform 31 10 1 1
182
183 subfc = ins "subfc" csv3 $ xoform 31 8 0 0
184 subfc_ = ins "subfc." csv3 $ xoform 31 8 0 1
185 subfco = ins "subfco" csv3 $ xoform 31 8 1 1
186 subfco_ = ins "subfco." csv3 $ xoform 31 8 1 1
187
188 adde = ins "adde" csv3 $ xoform 31 138 0 0
189 adde_ = ins "adde." csv3 $ xoform 31 138 0 1
190 addeo = ins "addeo" csv3 $ xoform 31 138 1 0
191 addeo_ = ins "addeo." csv3 $ xoform 31 138 1 1
192
193 subfe = ins "subfe" csv3 $ xoform 31 136 0 0
194 subfe_ = ins "subfe." csv3 $ xoform 31 136 0 1
195 subfeo = ins "subfeo" csv3 $ xoform 31 136 1 0
196 subfeo_ = ins "subfeo." csv3 $ xoform 31 136 1 1
197
198 addme = ins "addme" csv2 $ xoform' 31 234 0 0
199 addme_ = ins "addme." csv2 $ xoform' 31 234 0 1
200 addmeo = ins "addmeo" csv2 $ xoform' 31 234 1 0
201 addmeo_ = ins "addmeo." csv2 $ xoform' 31 234 1 1
202
203 subfme = ins "subfme" csv2 $ xoform' 31 232 0 0
204 subfme_ = ins "subfme." csv2 $ xoform' 31 232 0 1
205 subfmeo = ins "subfmeo" csv2 $ xoform' 31 232 1 0
206 subfmeo_ = ins "subfmeo." csv2 $ xoform' 31 232 1 1
207
208 addze = ins "addze" csv2 $ xoform' 31 202 0 0
209 addze_ = ins "addze." csv2 $ xoform' 31 202 0 1
210 addzeo = ins "addzeo" csv2 $ xoform' 31 202 1 0
211 addzeo_ = ins "addzeo." csv2 $ xoform' 31 202 1 1
212
213 subfze = ins "subfze" csv2 $ xoform' 31 202 0 0
214 subfze_ = ins "subfze." csv2 $ xoform' 31 202 0 1
215 subfzeo = ins "subfzeo" csv2 $ xoform' 31 202 1 0
216 subfzeo_ = ins "subfzeo." csv2 $ xoform' 31 202 1 1
217
218 neg = ins "neg" csv2 $ xoform' 31 104 0 0
219 neg_ = ins "neg." csv2 $ xoform' 31 104 0 1
220 nego = ins "nego" csv2 $ xoform' 31 104 1 0
221 nego_ = ins "nego." csv2 $ xoform' 31 104 1 1
222
223 mulli = ins "mulli" csv3 $ dform'a 7
224
225 mulld = ins "mulld" csv3 $ xoform 31 233 0 0
226 mulld_ = ins "mulld." csv3 $ xoform 31 233 0 1
227 mulldo = ins "mulldo" csv3 $ xoform 31 233 1 0
228 mulldo_ = ins "mulldo." csv3 $ xoform 31 233 1 1
229
230 mullw = ins "mullw" csv3 $ xoform 31 235 0 0
231 mullw_ = ins "mullw." csv3 $ xoform 31 235 0 1
232 mullwo = ins "mullwo" csv3 $ xoform 31 235 1 0
233 mullwo_ = ins "mullwo." csv3 $ xoform 31 235 1 1
234
235 mulhd = ins "mulhd" csv3 $ xoform 31 73 0 0
236 mulhd_ = ins "mulhd." csv3 $ xoform 31 73 0 1
237
238 mulhw = ins "mulhw" csv3 $ xoform 31 75 0 0
239 mulhw_ = ins "mulhw." csv3 $ xoform 31 75 0 1
240
241 mulhdu = ins "mulhdu" csv3 $ xoform 31 9 0 0
242 mulhdu_ = ins "mulhdu." csv3 $ xoform 31 9 0 1
243
244 mulhwu = ins "mulhwu" csv3 $ xoform 31 11 0 0
245 mulhwu_ = ins "mulhwu." csv3 $ xoform 31 11 0 1
246
247 divd = ins "divd" csv3 $ xoform 31 489 0 0
248 divd_ = ins "divd." csv3 $ xoform 31 489 0 1
249 divdo = ins "divdo" csv3 $ xoform 31 489 1 0
250 divdo_ = ins "divdo." csv3 $ xoform 31 489 1 1
251
252 divw = ins "divw" csv3 $ xoform 31 491 0 0
253 divw_ = ins "divw." csv3 $ xoform 31 491 0 1
254 divwo = ins "divwo" csv3 $ xoform 31 491 1 0
255 divwo_ = ins "divwo." csv3 $ xoform 31 491 1 1
256
257 divdu = ins "divdu" csv3 $ xoform 31 457 0 0
258 divdu_ = ins "divdu." csv3 $ xoform 31 457 0 1
259 divduo = ins "divduo" csv3 $ xoform 31 457 1 0
260 divduo_ = ins "divduo." csv3 $ xoform 31 457 1 1
261
262 divwu = ins "divwu" csv3 $ xoform 31 459 0 0
263 divwu_ = ins "divwu." csv3 $ xoform 31 459 0 1
264 divwuo = ins "divdwo" csv3 $ xoform 31 459 1 0
265 divwuo_ = ins "divdwo." csv3 $ xoform 31 459 1 1
266
267 -- fixed-point compare instructions
268 -- check out bit 9 in cmp
269 cmpi = ins "cmpi" csv3 $ dform'b 11 0
270 -- check out bit 9 in cmp
271 cmp = ins "cmp" csv3 $ xform'b 31 0 0
272 -- check out bit 9 in cmpli
273 cmpli = ins "cmpli" csv3 $ dform'b 10 0
274 -- check out bit 9 in cmpl
275 cmpl = ins "cmpl" csv3 $ xform'b 32 0 0
276
277 -- fixed-point trap instructions
278 tdi = ins "tdi" csv3 $ dform'a 2
279 twi = ins "twi" csv3 $ dform'a 3
280 td = ins "td" csv3 $ xform'a 31 68
281 tw = ins "tw" csv3 $ xform'a 31 4
282
283 -- fixed-point logical instructions
284 andi_ = ins "andi." csv3 $ dform'a 28
285 andis_ = ins "andis" csv3 $ dform'a 29
286 ori = ins "ori" csv3 $ dform'a 24
287 oris = ins "oris" csv3 $ dform'a 25
288 xori = ins "ori" csv3 $ dform'a 26
289 xors = ins "oris" csv3 $ dform'a 27
290 and = ins "and" csv3 $ xform'c 31 28 0
291 and_ = ins "and." csv3 $ xform'c 31 28 1
292 or = ins "or" csv3 $ xform'c 31 444 0
293 or_ = ins "or." csv3 $ xform'c 31 444 1
294 xor = ins "xor" csv3 $ xform'c 31 316 0
295 xor_ = ins "xor." csv3 $ xform'c 31 316 1
296 nand = ins "nand" csv3 $ xform'c 31 476 0
297 nand_ = ins "nand." csv3 $ xform'c 31 476 1
298 nor = ins "nor" csv3 $ xform'c 31 124 0
299 nor_ = ins "nor." csv3 $ xform'c 31 124 1
300 eqv = ins "eqv" csv3 $ xform'c 31 284 0
301 eqv_ = ins "eqv." csv3 $ xform'c 31 284 1
302 andc = ins "andc" csv3 $ xform'c 31 60 0
303 andc_ = ins "andc." csv3 $ xform'c 31 60 1
304 orc = ins "orc" csv3 $ xform'c 31 412 0
305 orc_ = ins "orc." csv3 $ xform'c 31 412 1
306 extsb = ins "extsb" csv2 $ xform'd 31 954 0
307 extsb_ = ins "extsb." csv2 $ xform'd 31 954 1
308 extsh = ins "extsh" csv2 $ xform'd 31 922 0
309 extsh_ = ins "extsh." csv2 $ xform'd 31 922 1
310 extsw = ins "extsw" csv2 $ xform'd 31 986 0
311 extsw_ = ins "extsw." csv2 $ xform'd 31 986 1
312 cntlzd = ins "cntlzd" csv2 $ xform'd 31 58 0
313 cntlzd_ = ins "cntlzd." csv2 $ xform'd 31 58 1
314 popcntb = ins "popcntb" csv2 $ xform'd 31 122 0
315 cntlzw = ins "cntlzw" csv2 $ xform'd 31 26 0
316 cntlzw_ = ins "cntlzw." csv2 $ xform'd 31 26 1
317
318 -- fixed-point rotate and shift instructions
319 rldicl  = ins "rldicl"  csv4 $ mdform 30 0 0
320 rldicl_ = ins "rldicl." csv4 $ mdform 30 0 1
321 rldicr  = ins "rldicr"  csv4 $ mdform 30 1 0
322 rldicr_ = ins "rldicr." csv4 $ mdform 30 1 1
323 rldic  = ins "rldic"  csv4 $ mdform 30 2 0
324 rldic_ = ins "rldic." csv4 $ mdform 30 2 1
325 rlwinm  = ins "rlwinm"  csv5 $ mform 21 0
326 rlwinm_ = ins "rlwinm." csv5 $ mform 21 1
327 rldcl  = ins "rldcl"  csv4 $ mdsform 30 8 0
328 rldcl_ = ins "rldcl." csv4 $ mdsform 30 8 1
329 rldcr  = ins "rldcr"  csv4 $ mdsform 30 9 0
330 rldcr_ = ins "rldcr." csv4 $ mdsform 30 9 1
331 rlwnm  = ins "rlwnm"  csv5 $ mform 23 0
332 rlwnm_ = ins "rlwnm." csv5 $ mform 23 1
333 rldimi  = ins "rldimi"  csv4 $ mdform 30 3 0
334 rldimi_ = ins "rldimi." csv4 $ mdform 30 3 1
335 rlwimi  = ins "rlwimi"  csv5 $ mform 20 0
336 rlwimi_ = ins "rlwimi." csv5 $ mform 20 1
337
338 -- fixed-point shift instructions
339 sld  = ins "sld"  csv3 $ xform'c 31 27 0
340 sld_ = ins "sld." csv3 $ xform'c 31 27 1
341 slw  = ins "slw"  csv3 $ xform'c 31 24 0
342 slw_ = ins "slw." csv3 $ xform'c 31 24 1
343 srd  = ins "srd"  csv3 $ xform'c 31 539 0
344 srd_ = ins "srd." csv3 $ xform'c 31 539 1
345 srw  = ins "srw"  csv3 $ xform'c 31 536 0
346 srw_ = ins "srw." csv3 $ xform'c 31 536 1
347 sradi  = ins "sradi"  csv3 $ xsform 31 413 0
348 sradi_ = ins "sradi." csv3 $ xsform 31 413 1
349 srawi  = ins "srawi"  csv3 $ xform'c 31 824 0
350 srawi_ = ins "srawi." csv3 $ xform'c 31 824 1
351 srad = ins "srad" csv3 $ xform'c 31 794 0
352 srad_ = ins "srad." csv3 $ xform'c 31 794 1
353 sraw = ins "sraw" csv3 $ xform'c 31 792 0
354 sraw_ = ins "sraw." csv3 $ xform'c 31 792 1
355
356 -- move to/from system register instructions
357 mtspr = ins "mtspr" csv2 $ xfxform 31 467
358 mfspr = ins "mfspr" csv2 $ xfxform 31 339
359 mtcrf = ins "mtcrf" csv2 $ xfxform'b 31 0 144
360
361 -- floating-point processor instructions --
362 -- floating-point load instructions
363 lfs = ins "lfs" csv3 $ dform'a 48
364
365
366 ---
367 ins m form e  = mnem m>>form e
368 v1 f = f<$>iLit
369 csv2 f =f<$>iLit<.>iLit
370 csv3 f = f<$>iLit<.>iLit<.>iLit
371 csv4 f = f<$>iLit<.>iLit<.>iLit<.>iLit
372 csv5 f = f<$>iLit<.>iLit<.>iLit<.>iLit<.>iLit
373
374 -- instruction fomats
375 iform opcd aa lk li = pack [(opcd,6),(li,30),(aa,31),(lk,0)]
376 bform opcd aa lk bo bi bd = pack [(opcd,6),(bo,11),(bi,16),(bd,30),(aa,31),(lk,0)]
377 scform opcd lev = pack [(opcd,6),(lev,27),(1,31)]
378 dform'a opcd rt ra d = pack [(opcd,6),(rt,11),(ra,16),(d,0)]
379 dform'b opcd bf l ra si = pack [(opcd,6),(bf,9),(0,10),(l,11),(ra,16),(si,0)]
380 dsform opcd rt ra ds xo = pack [(opcd,6),(rt,11),(ra,16),(ds,30),(xo,0)]
381 xform'a opcd rt ra rb xo = pack [(opcd,6),(rt,11),(ra,16),(rb,21),(xo,31)]
382 xform'b opcd xo bf l ra rb = pack [(opcd,6),(bf,9),(0,10),(l,11),(ra,16),(rb,21),(xo,31),(0,0)]
383 xform'c opcd xo rs ra rb rc = pack [(opcd,6),(rs,11),(ra,16),(rb,21),(xo,31),(rc,0)]
384 xform'd opcd xo rc rs ra = pack [(opcd,6),(rs,11),(ra,16),(0,21),(xo,31),(rc,0)]
385 xlform'a opcd xo bt ba bb = pack [(opcd,6),(bt,11),(ba,16),(bb,21),(xo,31)]
386 xlform'b opcd xo lk bo bi bh = pack [(opcd,6),(bo,11),(bi,16),(bh,21),(xo,31),(lk,0)]
387 xlform'c opcd xo bf bfa = pack [(opcd,6),(bf,9),(bfa,14),(xo,31)]
388 xfxform opcd xo rs spr = pack [(opcd,6),(rs,11),(spr,21),(xo,31)]
389 xfxform'b opcd h xo fxm rs = pack [(opcd,6),(rs,11),(h,12),(fxm,20),(xo,31)]
390 --xflform
391 -- fix xsform
392 xsform opcd xo rc ra rs sh = pack [(opcd,6),(rs,11),(ra,16),(sh,21),(xo,30),(sh,31),(rc,0)]
393 xoform opcd xo oe rc rt ra rb = pack [(opcd,6),(rt,11),(ra,16),(rb,21),(oe,22),(xo,31),(rc,0)]
394 xoform' opcd xo oe rc rt ra = pack [(opcd,6),(rt,11),(ra,16),(0,21),(oe,22),(xo,31),(rc,0)]
395 --aform
396 mform opcd rc ra rs sh mb me = pack [(opcd,6),(rs,11),(ra,16),(sh,21),(mb,26),(me,31),(rc,0)]
397 -- mdform needs to be fixed to handle sh correctly
398 mdform opcd h rc ra rs sh mb = pack [(opcd,6),(rs,11),(ra,16),(sh,21),(mb,27),(h,30),(sh,31),(rc,0)]
399 mdsform opcd h rc ra rs rb mb = pack [(opcd,6),(rs,11),(ra,16),(rb,21),(mb,27),(h,31),(rc,0)]
400
401 -- bit-packing --
402 pack bf = foldr1 (.|.) $ map (uncurry rotateR) bf
403