aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/ppc/hipe_ppc_encode.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/ppc/hipe_ppc_encode.erl')
-rw-r--r--lib/hipe/ppc/hipe_ppc_encode.erl1558
1 files changed, 1558 insertions, 0 deletions
diff --git a/lib/hipe/ppc/hipe_ppc_encode.erl b/lib/hipe/ppc/hipe_ppc_encode.erl
new file mode 100644
index 0000000000..97cb0bf635
--- /dev/null
+++ b/lib/hipe/ppc/hipe_ppc_encode.erl
@@ -0,0 +1,1558 @@
+%%% -*- erlang-indent-level: 4 -*-
+%%%
+%%% %CopyrightBegin%
+%%%
+%%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%%
+%%% The contents of this file are subject to the Erlang Public License,
+%%% Version 1.1, (the "License"); you may not use this file except in
+%%% compliance with the License. You should have received a copy of the
+%%% Erlang Public License along with this software. If not, it can be
+%%% retrieved online at http://www.erlang.org/.
+%%%
+%%% Software distributed under the License is distributed on an "AS IS"
+%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%%% the License for the specific language governing rights and limitations
+%%% under the License.
+%%%
+%%% %CopyrightEnd%
+%%%
+%%% Encode symbolic PowerPC instructions to binary form.
+%%% Copyright (C) 2003-2005, 2009 Mikael Pettersson
+%%%
+%%% Notes:
+%%% - PowerPC manuals use reversed bit numbering. In a 32-bit word,
+%%% the most significant bit has number 0, and the least significant
+%%% bit has number 31.
+%%% - PowerPC manuals list opcodes in decimal, not hex.
+%%% - This module does not support AltiVec instructions.
+%%%
+%%% Instruction Operands:
+%%%
+%%% {li,LI} long branch offset/address (24 bits, signed)
+%%% {bo,BO} branch control operand (5 bits, restricted)
+%%% {bi,BI} branch CR field and bits operand (5 bits)
+%%% {bd,BD} branch offset (14 bits, signed)
+%%% {to,TO} trap condition (5 bits)
+%%% {nb,NB} number of bytes to copy (5 bits)
+%%% {sh,SH} shift count (5 bits)
+%%% {mb,MB} mask begin bit number (5 bits)
+%%% {mb6,MB6} mask begin bit number (6 bits) (64-bit)
+%%% {me,ME} mask end bit number (5 bits)
+%%% {me6,ME6} mask end bit number (6 bits) (64-bit)
+%%% {sr,SR} segment register (4 bits)
+%%% {crimm,IMM} FPSCR CR image (4 bits)
+%%% {simm,SIMM} immediate operand (16 bits, signed)
+%%% {uimm,UIMM} immediate operand (16 bits, unsigned)
+%%% {d,Disp} load/store byte displacement (16 bits, signed)
+%%% {ds,DS} load/store word displacement (14 bits, signed) (64-bit)
+%%% {r,R} integer register (5 bits)
+%%% {fr,FR} floating-point register (5 bits)
+%%% {crf,CRF} CR field number (3 bits)
+%%% {crb,CRB} CR bit number (5 bits)
+%%% {tbr,TBR} TBR number (10 bits, 268 or 269)
+%%% {spr,SPR} SPR number (10 bits)
+%%% {crm,CRM} CR fields set (8 bits)
+%%% {fm,FM} FPSCR fields set (8 bits)
+
+-module(hipe_ppc_encode).
+
+-export([insn_encode/2]).
+
+%-define(TESTING,1).
+-ifdef(TESTING).
+-export([dotest/0, dotest/1]).
+-endif.
+
+-define(ASSERT(G), if G -> [] ; true -> exit({assertion_failed,?MODULE,?LINE,??G}) end).
+
+-define(BF(LB,RB,V), bf(LB,RB,V)).
+
+bf(LeftBit, RightBit, Value) ->
+ ?ASSERT(LeftBit >= 0),
+ ?ASSERT(LeftBit =< RightBit),
+ ?ASSERT(RightBit < 32),
+ ?ASSERT(Value >= 0),
+ ?ASSERT(Value < (1 bsl ((RightBit - LeftBit) + 1))),
+ Value bsl (31 - RightBit).
+
+-define(BIT(Pos,Val), ?BF(Pos,Pos,Val)).
+-define(BITS(N,Val), ?BF(32-N,31,Val)).
+
+%%% I-Form Instructions
+%%% b, ba, bl, bla
+
+b_AA_LK({{li,LI}}, AA, LK) ->
+ ?BF(0,5,10#18) bor ?BF(6,29,LI) bor ?BIT(30,AA) bor ?BIT(31,LK).
+
+%%% B-Form Instructions
+%%% bc, bca, bcl, bcla
+
+bc_AA_LK({{bo,BO}, {bi,BI}, {bd,BD}}, AA, LK) ->
+ ?BF(0,5,10#16) bor ?BF(6,10,BO) bor ?BF(11,15,BI) bor ?BF(16,29,BD) bor ?BIT(30,AA) bor ?BIT(31,LK).
+
+%%% SC-Form Instructions
+%%% sc
+
+sc({}) ->
+ ?BF(0,5,10#17) bor ?BIT(30,1).
+
+%%% D-Form Instructions
+%%% addi, addic, addic., addis, mulli, subfic
+%%% andi., andis., ori, oris, xori, xoris
+%%% lbz, lbzu, lha, lhau, lhz, lhzu, lwz, lwzu, lfd, lfdu, lfs, lfsu, lmw
+%%% stb, stbu, sth, sthu, stw, stwu, stfd, stfdu, stfs, stfsu, stmw
+%%% cmpi, cmpli, twi
+%%% tdi (64-bit)
+
+d_form(OPCD, D, A, IMM) ->
+ ?BF(0,5,OPCD) bor ?BF(6,10,D) bor ?BF(11,15,A) bor ?BF(16,31,IMM).
+
+d_form_D_A_SIMM(OPCD, {{r,D}, {r,A}, {simm,SIMM}}) ->
+ d_form(OPCD, D, A, SIMM).
+
+addi(Opnds) -> d_form_D_A_SIMM(10#14, Opnds).
+addic(Opnds) -> d_form_D_A_SIMM(10#12, Opnds).
+addic_dot(Opnds) -> d_form_D_A_SIMM(10#13, Opnds).
+addis(Opnds) -> d_form_D_A_SIMM(10#15, Opnds).
+mulli(Opnds) -> d_form_D_A_SIMM(10#07, Opnds).
+subfic(Opnds) -> d_form_D_A_SIMM(10#08, Opnds).
+
+d_form_S_A_UIMM(OPCD, {{r,A}, {r,S}, {uimm,UIMM}}) ->
+ d_form(OPCD, S, A, UIMM).
+
+andi_dot(Opnds) -> d_form_S_A_UIMM(10#28, Opnds).
+andis_dot(Opnds) -> d_form_S_A_UIMM(10#29, Opnds).
+ori(Opnds) -> d_form_S_A_UIMM(10#24, Opnds).
+oris(Opnds) -> d_form_S_A_UIMM(10#25, Opnds).
+xori(Opnds) -> d_form_S_A_UIMM(10#26, Opnds).
+xoris(Opnds) -> d_form_S_A_UIMM(10#27, Opnds).
+
+d_form_D_A_d_simple(OPCD, {{r,D}, {d,Disp}, {r,A}}) ->
+ d_form(OPCD, D, A, Disp).
+
+d_form_D_A_d_update(OPCD, {{r,D}, {d,Disp}, {r,A}}) ->
+ ?ASSERT(A =/= 0),
+ ?ASSERT(A =/= D),
+ d_form(OPCD, D, A, Disp).
+
+lbz(Opnds) -> d_form_D_A_d_simple(10#34, Opnds).
+lbzu(Opnds) -> d_form_D_A_d_update(10#35, Opnds).
+lha(Opnds) -> d_form_D_A_d_simple(10#42, Opnds).
+lhau(Opnds) -> d_form_D_A_d_update(10#43, Opnds).
+lhz(Opnds) -> d_form_D_A_d_simple(10#40, Opnds).
+lhzu(Opnds) -> d_form_D_A_d_update(10#41, Opnds).
+lwz(Opnds) -> d_form_D_A_d_simple(10#32, Opnds).
+lwzu(Opnds) -> d_form_D_A_d_update(10#33, Opnds).
+
+d_form_frD_A_d_simple(OPCD, {{fr,D}, {d,Disp}, {r,A}}) ->
+ d_form(OPCD, D, A, Disp).
+
+d_form_frD_A_d_update(OPCD, {{fr,D}, {d,Disp}, {r,A}}) ->
+ ?ASSERT(A =/= 0),
+ d_form(OPCD, D, A, Disp).
+
+lfd(Opnds) -> d_form_frD_A_d_simple(10#50, Opnds).
+lfdu(Opnds) -> d_form_frD_A_d_update(10#51, Opnds).
+lfs(Opnds) -> d_form_frD_A_d_simple(10#48, Opnds).
+lfsu(Opnds) -> d_form_frD_A_d_update(10#49, Opnds).
+
+lmw({{r,D}, {d,Disp}, {r,A}}) ->
+ ?ASSERT(A < D),
+ d_form(10#46, D, A, Disp).
+
+d_form_S_A_d_simple(OPCD, {{r,S}, {d,Disp}, {r,A}}) ->
+ d_form(OPCD, S, A, Disp).
+
+d_form_S_A_d_update(OPCD, {{r,S}, {d,Disp}, {r,A}}) ->
+ ?ASSERT(A =/= 0),
+ d_form(OPCD, S, A, Disp).
+
+stb(Opnds) -> d_form_S_A_d_simple(10#38, Opnds).
+stbu(Opnds) -> d_form_S_A_d_update(10#39, Opnds).
+sth(Opnds) -> d_form_S_A_d_simple(10#44, Opnds).
+sthu(Opnds) -> d_form_S_A_d_update(10#45, Opnds).
+stmw(Opnds) -> d_form_S_A_d_simple(10#47, Opnds).
+stw(Opnds) -> d_form_S_A_d_simple(10#36, Opnds).
+stwu(Opnds) -> d_form_S_A_d_update(10#37, Opnds).
+
+d_form_frS_A_d_simple(OPCD, {{fr,S}, {d,Disp}, {r,A}}) ->
+ d_form(OPCD, S, A, Disp).
+
+d_form_frS_A_d_update(OPCD, {{fr,S}, {d,Disp}, {r,A}}) ->
+ ?ASSERT(A =/= 0),
+ d_form(OPCD, S, A, Disp).
+
+stfd(Opnds) -> d_form_frS_A_d_simple(10#54, Opnds).
+stfdu(Opnds) -> d_form_frS_A_d_update(10#55, Opnds).
+stfs(Opnds) -> d_form_frS_A_d_simple(10#52, Opnds).
+stfsu(Opnds) -> d_form_frS_A_d_update(10#53, Opnds).
+
+cmpi({{crf,CRFD}, L, {r,A}, {simm,SIMM}}) ->
+ %% ?ASSERT(L == 0), % L must be zero in 32-bit code
+ d_form(10#11, (CRFD bsl 2) bor L, A, SIMM).
+
+cmpli({{crf,CRFD}, L, {r,A}, {uimm,UIMM}}) ->
+ %% ?ASSERT(L == 0), % L must be zero in 32-bit code
+ d_form(10#10, (CRFD bsl 2) bor L, A, UIMM).
+
+d_form_OPCD_TO_A_SIMM(OPCD, {{to,TO}, {r,A}, {simm,SIMM}}) ->
+ d_form(OPCD, TO, A, SIMM).
+
+tdi(Opnds) -> d_form_OPCD_TO_A_SIMM(10#02, Opnds). % 64-bit
+twi(Opnds) -> d_form_OPCD_TO_A_SIMM(10#03, Opnds).
+
+%%% DS-Form Instructions
+%%% ld, ldu, lwa, std, stdu (64-bit)
+
+ds_form(OPCD, D, A, DS, XO) ->
+ ?BF(0,5,OPCD) bor ?BF(6,10,D) bor ?BF(11,15,A) bor ?BF(16,29,DS) bor ?BF(30,31,XO).
+
+ds_form_D_A_DS_XO_simple(OPCD, {{r,D}, {ds,DS}, {r,A}}, XO) ->
+ ds_form(OPCD, D, A, DS, XO).
+
+ds_form_D_A_DS_XO_update(OPCD, {{r,D}, {ds,DS}, {r,A}}, XO) ->
+ ?ASSERT(A =/= 0),
+ ?ASSERT(A =/= D),
+ ds_form(OPCD, D, A, DS, XO).
+
+ld(Opnds) -> ds_form_D_A_DS_XO_simple(10#58, Opnds, 10#0). % 64-bit
+ldu(Opnds) -> ds_form_D_A_DS_XO_update(10#58, Opnds, 10#1). % 64-bit
+lwa(Opnds) -> ds_form_D_A_DS_XO_simple(10#58, Opnds, 10#2). % 64-bit
+std(Opnds) -> ds_form_D_A_DS_XO_simple(10#62, Opnds, 10#0). % 64-bit
+stdu(Opnds) -> ds_form_D_A_DS_XO_update(10#62, Opnds, 10#1). % 64-bit
+
+%%% X-Form Instructions
+%%% ecixw, lbzux, lbzx, lhaux, lhax, lhbrx, lhzux, lhzx, lwarx, lwbrx, lwzux, lwzx, lswx
+%%% lwaux, lwax (64-bit)
+%%% lfdux, lfdx, lfsux, lfsx
+%%% lswi
+%%% fabs, fctiw, fctiwz, fmr, fnabs, fneg, frsp
+%%% fcfid, fctid, fctidz (64-bit)
+%%% mfsrin
+%%% mffs
+%%% mfcr, mfmsr
+%%% mfsr
+%%% and, andc, eqv, nand, nor, or, orc, slw, sraw, srw, xor
+%%% sld, srad, srd (64-bit)
+%%% stwcx.
+%%% stdcx. (64-bit)
+%%% ecowx, stbx, stbux, sthbrx, sthx, sthux, stswx, stwbrx, stwx, stwux
+%%% stdux, stdx (64-bit)
+%%% stfdx, stfdux, stfiwx, stfsx, stfsux
+%%% stswi
+%%% cntlzw, extsb, extsh
+%%% cntlzd, extsw (64-bit)
+%%% mtmsr
+%%% mtmsrd (64-bit)
+%%% mtsr, mtsrin
+%%% mtsrd, mtsrdin (64-bit)
+%%% srawi
+%%% sradi (64-bit)
+%%% cmp, cmpl
+%%% fcmpo, fcmpu
+%%% mcrfs
+%%% mcrxr (obsolete)
+%%% mtfsfi
+%%% tw
+%%% td (64-bit)
+%%% mtfsb0, mtfsb1
+%%% dcba, dcbf, dcbi, dcbst, dcbt, dcbtst, dcbz, icbi
+%%% tlbie
+%%% eieio, sync, tlbia, tlbsync
+
+x_form(OPCD, D, A, B, XO, Rc) ->
+ ?BF(0,5,OPCD) bor ?BF(6,10,D) bor ?BF(11,15,A) bor ?BF(16,20,B) bor ?BF(21,30,XO) bor ?BIT(31,Rc).
+
+x_form_D_A_B_XO_simple({{r,D}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, D, A, B, XO, 0).
+
+x_form_D_A_B_XO_update({{r,D}, {r,A}, {r,B}}, XO) ->
+ ?ASSERT(A =/= 0),
+ ?ASSERT(A =/= D),
+ x_form(10#31, D, A, B, XO, 0).
+
+eciwx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#310). % optional
+lbzux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#119).
+lbzx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#87).
+ldarx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#84). % 64-bit
+ldux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#53). % 64-bit
+ldx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#21). % 64-bit
+lhaux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#375).
+lhax(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#343).
+lhbrx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#790).
+lhzux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#311).
+lhzx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#279).
+lswx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#533). % XXX: incomplete checks
+lwarx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#20).
+lwaux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#373). % 64-bit
+lwax(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#341). % 64-bit
+lwbrx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#534).
+lwzux(Opnds) -> x_form_D_A_B_XO_update(Opnds, 10#55).
+lwzx(Opnds) -> x_form_D_A_B_XO_simple(Opnds, 10#23).
+
+x_form_frD_A_B_XO_simple({{fr,D}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, D, A, B, XO, 0).
+
+x_form_frD_A_B_XO_update({{fr,D}, {r,A}, {r,B}}, XO) ->
+ ?ASSERT(A =/= 0),
+ x_form(10#31, D, A, B, XO, 0).
+
+lfdux(Opnds) -> x_form_frD_A_B_XO_update(Opnds, 10#631).
+lfdx(Opnds) -> x_form_frD_A_B_XO_simple(Opnds, 10#599).
+lfsux(Opnds) -> x_form_frD_A_B_XO_update(Opnds, 10#567).
+lfsx(Opnds) -> x_form_frD_A_B_XO_simple(Opnds, 10#535).
+
+lswi({{r,D}, {r,A}, {nb,NB}}) -> % XXX: incomplete checks
+ x_form(10#31, D, A, NB, 10#597, 0).
+
+x_form_D_B_XO_Rc({{fr,D}, {fr,B}}, XO, Rc) ->
+ x_form(10#63, D, 0, B, XO, Rc).
+
+fabs_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#264, Rc).
+fcfid_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#846, Rc). % 64-bit
+fctid_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#814, Rc). % 64-bit
+fctidz_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#815, Rc). % 64-bit
+fctiw_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#14, Rc).
+fctiwz_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#15, Rc).
+fmr_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#72, Rc).
+fnabs_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#136, Rc).
+fneg_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#40, Rc).
+frsp_Rc(Opnds, Rc) -> x_form_D_B_XO_Rc(Opnds, 10#12, Rc).
+
+mfsrin({{r,D}, {r,B}}) -> % supervisor
+ x_form(10#31, D, 0, B, 10#659, 0).
+
+mffs_Rc({{fr,D}}, Rc) ->
+ x_form(10#63, D, 0, 0, 10#583, Rc).
+
+x_form_D_XO({{r,D}}, XO) ->
+ x_form(10#31, D, 0, 0, XO, 0).
+
+mfcr(Opnds) -> x_form_D_XO(Opnds, 10#19).
+mfmsr(Opnds) -> x_form_D_XO(Opnds, 10#83). % supervisor
+
+mfsr({{r,D}, {sr,SR}}) -> % supervisor
+ x_form(10#31, D, ?BITS(4,SR), 0, 10#595, 0).
+
+x_form_S_A_B_XO_Rc({{r,A}, {r,S}, {r,B}}, XO, Rc) ->
+ x_form(10#31, S, A, B, XO, Rc).
+
+and_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#28, Rc).
+andc_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#60, Rc).
+eqv_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#284, Rc).
+nand_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#476, Rc).
+nor_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#124, Rc).
+or_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#444, Rc).
+orc_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#412, Rc).
+sld_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#27, Rc). % 64-bit
+slw_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#24, Rc).
+srad_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#794, Rc). % 64-bit
+sraw_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#792, Rc).
+srd_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#539, Rc). % 64-bit
+srw_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#536, Rc).
+xor_Rc(Opnds, Rc) -> x_form_S_A_B_XO_Rc(Opnds, 10#316, Rc).
+
+xform_S_A_B_XO_1({{r,S}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, S, A, B, XO, 1).
+
+stdcx_dot(Opnds) -> xform_S_A_B_XO_1(Opnds, 10#214). % 64-bit
+stwcx_dot(Opnds) -> xform_S_A_B_XO_1(Opnds, 10#150).
+
+x_form_S_A_B_XO_simple({{r,S}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, S, A, B, XO, 0).
+
+x_form_S_A_B_XO_update({{r,S}, {r,A}, {r,B}}, XO) ->
+ ?ASSERT(A =/= 0),
+ x_form(10#31, S, A, B, XO, 0).
+
+ecowx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#438). % optional
+stbx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#215).
+stbux(Opnds) -> x_form_S_A_B_XO_update(Opnds, 10#247).
+sthbrx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#918).
+stdx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#149). % 64-bit
+stdux(Opnds) -> x_form_S_A_B_XO_update(Opnds, 10#181). % 64-bit
+sthx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#407).
+sthux(Opnds) -> x_form_S_A_B_XO_update(Opnds, 10#439).
+stswx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#661).
+stwbrx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#662).
+stwx(Opnds) -> x_form_S_A_B_XO_simple(Opnds, 10#151).
+stwux(Opnds) -> x_form_S_A_B_XO_update(Opnds, 10#183).
+
+x_form_frS_A_B_XO_simple({{fr,S}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, S, A, B, XO, 0).
+
+x_form_frS_A_B_XO_update({{fr,S}, {r,A}, {r,B}}, XO) ->
+ ?ASSERT(A =/= 0),
+ x_form(10#31, S, A, B, XO, 0).
+
+stfdx(Opnds) -> x_form_frS_A_B_XO_simple(Opnds, 10#727).
+stfdux(Opnds) -> x_form_frS_A_B_XO_update(Opnds, 10#759).
+stfiwx(Opnds) -> x_form_frS_A_B_XO_simple(Opnds, 10#983). % optional
+stfsx(Opnds) -> x_form_frS_A_B_XO_simple(Opnds, 10#663).
+stfsux(Opnds) -> x_form_frS_A_B_XO_update(Opnds, 10#695).
+
+stswi({{r,S}, {r,A}, {nb,NB}}) ->
+ x_form(10#31, S, A, NB, 10#725, 0).
+
+x_form_S_A_XO_Rc({{r,A}, {r,S}}, XO, Rc) ->
+ x_form(10#31, S, A, 0, XO, Rc).
+
+cntlzd_Rc(Opnds, Rc) -> x_form_S_A_XO_Rc(Opnds, 10#58, Rc). % 64-bit
+cntlzw_Rc(Opnds, Rc) -> x_form_S_A_XO_Rc(Opnds, 10#26, Rc).
+extsb_Rc(Opnds, Rc) -> x_form_S_A_XO_Rc(Opnds, 10#954, Rc).
+extsh_Rc(Opnds, Rc) -> x_form_S_A_XO_Rc(Opnds, 10#922, Rc).
+extsw_Rc(Opnds, Rc) -> x_form_S_A_XO_Rc(Opnds, 10#986, Rc). % 64-bit
+
+mtmsr({{r,S}}) -> % supervisor
+ x_form(10#31, S, 0, 0, 10#146, 0).
+
+mtmsrd({{r,S}}) -> % supervisor, 64-bit
+ x_form(10#31, S, 0, 0, 10#178, 0).
+
+mtsr({{sr,SR}, {r,S}}) -> % supervisor
+ x_form(10#31, S, ?BITS(4,SR), 0, 10#210, 0).
+
+mtsrd({{sr,SR}, {r,S}}) -> % supervisor, 64-bit
+ x_form(10#31, S, ?BITS(4,SR), 0, 10#82, 0).
+
+mtsrdin({{r,S}, {r,B}}) -> % supervisor, 64-bit
+ x_form(10#31, S, 0, B, 10#114, 0).
+
+mtsrin({{r,S}, {r,B}}) -> % supervisor, 32-bit
+ x_form(10#31, S, 0, B, 10#242, 0).
+
+slbia({}) -> % supervisor, 64-bit
+ x_form(10#31, 0, 0, 0, 10#498, 0).
+
+slbie({{r,B}}) -> % supervisor, 64-bit
+ x_form(10#31, 0, 0, B, 10#434, 0).
+
+srawi_Rc({{r,A}, {r,S}, {sh,SH}}, Rc) ->
+ x_form(10#31, S, A, SH, 10#824, Rc).
+
+x_form_crfD_L_A_B_XO({{crf,CRFD}, L, {r,A}, {r,B}}, XO) ->
+ %% ?ASSERT(L == 0), % L should be zero in 32-bit code
+ x_form(10#31, (CRFD bsl 2) bor L, A, B, XO, 0).
+
+cmp(Opnds) -> x_form_crfD_L_A_B_XO(Opnds, 0).
+cmpl(Opnds) -> x_form_crfD_L_A_B_XO(Opnds, 10#32).
+
+x_form_crfD_A_B_XO({{crf,CRFD}, {fr,A}, {fr,B}}, XO) ->
+ x_form(10#63, CRFD bsl 2, A, B, XO, 0).
+
+fcmpo(Opnds) -> x_form_crfD_A_B_XO(Opnds, 10#32).
+fcmpu(Opnds) -> x_form_crfD_A_B_XO(Opnds, 0).
+
+mcrfs({{crf,CRFD}, {crf,CRFS}}) ->
+ x_form(10#63, CRFD bsl 2, CRFS bsl 2, 0, 10#64, 0).
+
+%% mcrxr({{crf,CRFD}}) ->
+%% x_form(10#31, CRFD bsl 2, 0, 0, 10#512, 0).
+
+mtfsfi_Rc({{crf,CRFD}, {crimm,IMM}}, Rc) ->
+ x_form(10#63, CRFD bsl 2, 0, IMM bsl 1, 10#134, Rc).
+
+x_form_TO_A_B_XO({{to,TO}, {r,A}, {r,B}}, XO) ->
+ x_form(10#31, TO, A, B, XO, 0).
+
+td(Opnds) -> x_form_TO_A_B_XO(Opnds, 10#68). % 64-bit
+tw(Opnds) -> x_form_TO_A_B_XO(Opnds, 10#4).
+
+x_form_crbD_XO_Rc({{crb,CRBD}}, XO, Rc) ->
+ x_form(10#63, CRBD, 0, 0, XO, Rc).
+
+mtfsb0_Rc(Opnds, Rc) -> x_form_crbD_XO_Rc(Opnds, 10#70, Rc).
+mtfsb1_Rc(Opnds, Rc) -> x_form_crbD_XO_Rc(Opnds, 10#38, Rc).
+
+x_form_A_B_XO({{r,A}, {r,B}}, XO) ->
+ x_form(10#31, 0, A, B, XO, 0).
+
+dcba(Opnds) -> x_form_A_B_XO(Opnds, 10#758). % optional
+dcbf(Opnds) -> x_form_A_B_XO(Opnds, 10#86).
+dcbi(Opnds) -> x_form_A_B_XO(Opnds, 10#470). % supervisor
+dcbst(Opnds) -> x_form_A_B_XO(Opnds, 10#54).
+dcbt(Opnds) -> x_form_A_B_XO(Opnds, 10#278).
+dcbtst(Opnds) -> x_form_A_B_XO(Opnds, 10#246).
+dcbz(Opnds) -> x_form_A_B_XO(Opnds, 10#1014).
+icbi(Opnds) -> x_form_A_B_XO(Opnds, 10#982).
+
+x_form_B_XO({{r,B}}, XO) ->
+ x_form(10#31, 0, 0, B, XO, 0).
+
+tlbie(Opnds) -> x_form_B_XO(Opnds, 10#306). % supervisor, optional
+tlbld(Opnds) -> x_form_B_XO(Opnds, 10#978). % supervisor, optional
+tlbli(Opnds) -> x_form_B_XO(Opnds, 10#1010). % supervisor, optional
+
+x_form_XO({}, XO) ->
+ x_form(10#31, 0, 0, 0, XO, 0).
+
+eieio(Opnds) -> x_form_XO(Opnds, 10#854).
+sync(Opnds) -> x_form_XO(Opnds, 10#598).
+tlbia(Opnds) -> x_form_XO(Opnds, 10#370). % supervisor, optional
+tlbsync(Opnds) -> x_form_XO(Opnds, 10#566). % supervisor, optional
+
+%%% XL-Form Instructions
+%%% bcctr, bclr
+%%% crand, crandc, creqv, crnand, crnor, cror, crorc, crxor
+%%% mcrf
+%%% isync, rfi
+%%% rfid (64-bit)
+
+xl_form(A, B, C, XO, LK) ->
+ ?BF(0,5,10#19) bor ?BF(6,10,A) bor ?BF(11,15,B) bor ?BF(16,20,C) bor ?BF(21,30,XO) bor ?BIT(31,LK).
+
+xl_form_BO_BI_XO_LK({{bo,BO}, {bi,BI}}, XO, LK) ->
+ xl_form(BO, BI, 0, XO, LK).
+
+bcctr_lk(Opnds, LK) -> xl_form_BO_BI_XO_LK(Opnds, 10#528, LK).
+bclr_lk(Opnds, LK) -> xl_form_BO_BI_XO_LK(Opnds, 10#16, LK).
+
+xl_form_crbD_crbA_crbB_XO({{crb,CRBD}, {crb,CRBA}, {crb,CRBB}}, XO) ->
+ xl_form(CRBD, CRBA, CRBB, XO, 0).
+
+crand(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#257).
+crandc(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#129).
+creqv(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#289).
+crnand(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#225).
+crnor(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#33).
+cror(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#449).
+crorc(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#417).
+crxor(Opnds) -> xl_form_crbD_crbA_crbB_XO(Opnds, 10#193).
+
+mcrf({{crf,CRFD}, {crf,CRFS}}) ->
+ xl_form(CRFD bsl 2, CRFS bsl 2, 0, 0, 0).
+
+xl_form_XO({}, XO) ->
+ xl_form(0, 0, 0, XO, 0).
+
+isync(Opnds) -> xl_form_XO(Opnds, 10#150).
+rfi(Opnds) -> xl_form_XO(Opnds, 10#50). % supervisor
+rfid(Opnds) -> xl_form_XO(Opnds, 10#18). % supervisor, 64-bit
+
+%%% XFX-Form Instructions
+%%% mfspr, mtspr, mftb, mtcrf
+
+xfx_form(A, B, XO) ->
+ ?BF(0,5,10#31) bor ?BF(6,10,A) bor ?BF(11,20,B) bor ?BF(21,30,XO).
+
+xfx_form_R_SPR_XO(R, SPR, XO) ->
+ SPR04 = SPR band 16#1F,
+ SPR59 = (SPR bsr 5) band 16#1F,
+ xfx_form(R, (SPR04 bsl 5) bor SPR59, XO).
+
+mfspr({{r,D}, {spr,SPR}}) -> xfx_form_R_SPR_XO(D, SPR, 10#339).
+mtspr({{spr,SPR}, {r,S}}) -> xfx_form_R_SPR_XO(S, SPR, 10#467).
+mftb({{r,D}, {tbr,TBR}}) -> xfx_form_R_SPR_XO(D, TBR, 10#371).
+
+mtcrf({{crm,CRM}, {r,S}}) -> xfx_form(S, ?BITS(8,CRM) bsl 1, 10#144).
+
+%%% XFL-Form Instructions
+%%% mtfsf
+
+xfl_form(FM, B, Rc) ->
+ ?BF(0,5,10#63) bor ?BF(7,14,FM) bor ?BF(16,20,B) bor ?BF(21,30,10#711) bor ?BIT(31,Rc).
+
+mtfsf_Rc({{fm,FM}, {fr,B}}, Rc) -> xfl_form(FM, B, Rc).
+
+%%% XS-Form Instructions
+%%% sradi (64-bit)
+
+xs_form(S, A, SH1, XO, SH2, Rc) ->
+ ?BF(0,5,10#31) bor ?BF(6,10,S) bor ?BF(11,15,A) bor ?BF(16,20,SH1) bor ?BF(21,29,XO) bor ?BIT(30,SH2) bor ?BIT(31,Rc).
+
+sradi_Rc({{r,A}, {r,S}, {sh6,SH6}}, Rc) -> % 64-bit
+ xs_form(S, A, sh6_bits0to4(SH6), 10#413, sh6_bit5(SH6), Rc).
+
+%%% XO-Form Instructions
+%%% add, addc, adde, divw, divwu, mullw, subf, subfc, subfe
+%%% divd, divdu, mulld (64-bit)
+%%% mulhw, mulhwu
+%%% mulhd, mulhdu (64-bit)
+%%% addme, addze, neg, subfme, subfze
+
+xo_form(D, A, B, OE, XO, Rc) ->
+ ?BF(0,5,10#31) bor ?BF(6,10,D) bor ?BF(11,15,A) bor ?BF(16,20,B) bor ?BIT(21,OE) bor ?BF(22,30,XO) bor ?BIT(31,Rc).
+
+xo_form_D_A_B_OE_XO_Rc({{r,D}, {r,A}, {r,B}}, OE, XO, Rc) ->
+ xo_form(D, A, B, OE, XO, Rc).
+
+add_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#266, Rc).
+addc_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#10, Rc).
+adde_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#138, Rc).
+divd_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#489, Rc). % 64-bit
+divdu_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#457, Rc). % 64-bit
+divw_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#491, Rc).
+divwu_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#459, Rc).
+mulld_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#233, Rc). % 64-bit
+mullw_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#235, Rc).
+subf_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#40, Rc).
+subfc_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#8, Rc).
+subfe_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, OE, 10#136, Rc).
+
+mulhd_Rc(Opnds, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, 0, 10#73, Rc). % 64-bit
+mulhdu_Rc(Opnds, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, 0, 10#9, Rc). % 64-bit
+mulhw_Rc(Opnds, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, 0, 10#75, Rc).
+mulhwu_Rc(Opnds, Rc) -> xo_form_D_A_B_OE_XO_Rc(Opnds, 0, 10#11, Rc).
+
+xo_form_D_A_OE_XO_Rc({{r,D}, {r,A}}, OE, XO, Rc) ->
+ xo_form(D, A, 0, OE, XO, Rc).
+
+addme_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_OE_XO_Rc(Opnds, OE, 10#234, Rc).
+addze_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_OE_XO_Rc(Opnds, OE, 10#202, Rc).
+neg_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_OE_XO_Rc(Opnds, OE, 10#104, Rc).
+subfme_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_OE_XO_Rc(Opnds, OE, 10#232, Rc).
+subfze_OE_Rc(Opnds, OE, Rc) -> xo_form_D_A_OE_XO_Rc(Opnds, OE, 10#200, Rc).
+
+%%% A-Form Instructions
+%%% fadd, fadds, fdiv, fdivs, fsub, fsubs
+%%% fmadd, fmadds, fmsub, fmsubs, fnmadd, fnmadds, fnmsub, fnmsubs, fsel
+%%% fmul, fmuls
+%%% fres, fsqrte, fsqrt, fsqrts
+
+a_form(OPCD, D, A, B, C, XO, Rc) ->
+ ?BF(0,5,OPCD) bor ?BF(6,10,D) bor ?BF(11,15,A) bor ?BF(16,20,B) bor ?BF(21,25,C) bor ?BF(26,30,XO) bor ?BIT(31,Rc).
+
+a_form_D_A_B_XO_Rc(OPCD, {{fr,D}, {fr,A}, {fr,B}}, XO, Rc) ->
+ a_form(OPCD, D, A, B, 0, XO, Rc).
+
+fadd_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_XO_Rc(OPCD, Opnds, 10#21, Rc).
+fadd_Rc(Opnds, Rc) -> fadd_OPCD_Rc(10#63, Opnds, Rc).
+fadds_Rc(Opnds, Rc) -> fadd_OPCD_Rc(10#59, Opnds, Rc).
+
+fdiv_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_XO_Rc(OPCD, Opnds, 10#18, Rc).
+fdiv_Rc(Opnds, Rc) -> fdiv_OPCD_Rc(10#63, Opnds, Rc).
+fdivs_Rc(Opnds, Rc) -> fdiv_OPCD_Rc(10#59, Opnds, Rc).
+
+fsub_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_XO_Rc(OPCD, Opnds, 10#20, Rc).
+fsub_Rc(Opnds, Rc) -> fsub_OPCD_Rc(10#63, Opnds, Rc).
+fsubs_Rc(Opnds, Rc) -> fsub_OPCD_Rc(10#59, Opnds, Rc).
+
+a_form_D_A_B_C_XO_Rc(OPCD, {{fr,D}, {fr,A}, {fr,C}, {fr,B}}, XO, Rc) ->
+ a_form(OPCD, D, A, B, C, XO, Rc).
+
+fmadd_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_C_XO_Rc(OPCD, Opnds, 10#29, Rc).
+fmadd_Rc(Opnds, Rc) -> fmadd_OPCD_Rc(10#63, Opnds, Rc).
+fmadds_Rc(Opnds, Rc) -> fmadd_OPCD_Rc(10#59, Opnds, Rc).
+
+fmsub_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_C_XO_Rc(OPCD, Opnds, 10#28, Rc).
+fmsub_Rc(Opnds, Rc) -> fmsub_OPCD_Rc(10#63, Opnds, Rc).
+fmsubs_Rc(Opnds, Rc) -> fmsub_OPCD_Rc(10#59, Opnds, Rc).
+
+fnmadd_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_C_XO_Rc(OPCD, Opnds, 10#31, Rc).
+fnmadd_Rc(Opnds, Rc) -> fnmadd_OPCD_Rc(10#63, Opnds, Rc).
+fnmadds_Rc(Opnds, Rc) -> fnmadd_OPCD_Rc(10#59, Opnds, Rc).
+
+fnmsub_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_A_B_C_XO_Rc(OPCD, Opnds, 10#30, Rc).
+fnmsub_Rc(Opnds, Rc) -> fnmsub_OPCD_Rc(10#63, Opnds, Rc).
+fnmsubs_Rc(Opnds, Rc) -> fnmsub_OPCD_Rc(10#59, Opnds, Rc).
+
+fsel_Rc(Opnds, Rc) -> a_form_D_A_B_C_XO_Rc(10#63, Opnds, 10#23, Rc). % optional
+
+fmul_OPCD_Rc(OPCD, {{fr,D}, {fr,A}, {fr,C}}, Rc) ->
+ a_form(OPCD, D, A, 0, C, 10#25, Rc).
+
+fmul_Rc(Opnds, Rc) -> fmul_OPCD_Rc(10#63, Opnds, Rc).
+fmuls_Rc(Opnds, Rc) -> fmul_OPCD_Rc(10#59, Opnds, Rc).
+
+a_form_D_B_XO_Rc(OPCD, {{fr,D}, {fr,B}}, XO, Rc) ->
+ a_form(OPCD, D, 0, B, 0, XO, Rc).
+
+fres_Rc(Opnds, Rc) -> a_form_D_B_XO_Rc(10#59, Opnds, 10#24, Rc). % optional
+frsqrte_Rc(Opnds, Rc) -> a_form_D_B_XO_Rc(10#63, Opnds, 10#26, Rc). % optional
+
+fsqrt_OPCD_Rc(OPCD, Opnds, Rc) -> a_form_D_B_XO_Rc(OPCD, Opnds, 10#22, Rc). % optional
+fsqrt_Rc(Opnds, Rc) -> fsqrt_OPCD_Rc(10#63, Opnds, Rc). % optional
+fsqrts_Rc(Opnds, Rc) -> fsqrt_OPCD_Rc(10#59, Opnds, Rc). % optional
+
+%%% M-Form Instructions
+%%% rlwimi, rlwinm
+%%% rlwnm
+
+m_form(OPCD, S, A, SH, MB, ME, Rc) ->
+ ?BF(0,5,OPCD) bor ?BF(6,10,S) bor ?BF(11,15,A) bor ?BF(16,20,SH) bor ?BF(21,25,MB) bor ?BF(26,30,ME) bor ?BIT(31,Rc).
+
+m_form_S_A_SH_MB_ME_Rc(OPCD, {{r,A}, {r,S}, {sh,SH}, {mb,MB}, {me,ME}}, Rc) ->
+ m_form(OPCD, S, A, SH, MB, ME, Rc).
+
+rlwimi_Rc(Opnds, Rc) -> m_form_S_A_SH_MB_ME_Rc(10#20, Opnds, Rc).
+rlwinm_Rc(Opnds, Rc) -> m_form_S_A_SH_MB_ME_Rc(10#21, Opnds, Rc).
+
+rlwnm_Rc({{r,A}, {r,S}, {r,B}, {mb,MB}, {me,ME}}, Rc) ->
+ m_form(10#23, S, A, B, MB, ME, Rc).
+
+%%% MD-Form Instructions
+%%% rldic, rldicl, rldicr, rldimi (64-bit)
+
+md_form(S, A, SH1, MB, XO, SH2, Rc) ->
+ ?BF(0,5,10#30) bor ?BF(6,10,S) bor ?BF(11,15,A) bor ?BF(16,20,SH1) bor ?BF(21,26,MB) bor ?BF(27,29,XO) bor ?BIT(30,SH2) bor ?BIT(31,Rc).
+
+mb6_reformat(MB6) ->
+ ((MB6 band 16#1F) bsl 1) bor ((MB6 bsr 5) band 1).
+
+sh6_bits0to4(SH6) ->
+ SH6 band 16#1F.
+
+sh6_bit5(SH6) ->
+ (SH6 bsr 5) band 1.
+
+md_form_S_A_SH6_MB6_XO_Rc({{r,A}, {r,S}, {sh6,SH6}, {mb6,MB6}}, XO, Rc) ->
+ md_form(S, A, sh6_bits0to4(SH6), mb6_reformat(MB6), XO, sh6_bit5(SH6), Rc).
+
+rldic_Rc(Opnds, Rc) -> md_form_S_A_SH6_MB6_XO_Rc(Opnds, 10#2, Rc). % 64-bit
+rldicl_Rc(Opnds, Rc) -> md_form_S_A_SH6_MB6_XO_Rc(Opnds, 10#0, Rc). % 64-bit
+rldimi_Rc(Opnds, Rc) -> md_form_S_A_SH6_MB6_XO_Rc(Opnds, 10#3, Rc). % 64-bit
+
+rldicr_Rc({{r,A}, {r,S}, {sh6,SH6}, {me6,ME6}}, Rc) -> % 64-bit
+ md_form(S, A, sh6_bits0to4(SH6), mb6_reformat(ME6), 10#1, sh6_bit5(SH6), Rc).
+
+%%% MDS-Form Instructions
+%%% rldcl, rldcr (64-bit)
+
+mds_form(S, A, B, MB, XO, Rc) ->
+ ?BF(0,5,10#30) bor ?BF(6,10,S) bor ?BF(11,15,A) bor ?BF(16,20,B) bor ?BF(21,26,MB) bor ?BF(27,30,XO) bor ?BIT(31,Rc).
+
+rldcl({{r,A}, {r,S}, {r,B}, {mb6,MB6}}, Rc) -> % 64-bit
+ mds_form(S, A, B, mb6_reformat(MB6), 10#8, Rc).
+
+rldcr({{r,A}, {r,S}, {r,B}, {me6,ME6}}, Rc) -> % 64-bit
+ mds_form(S, A, B, mb6_reformat(ME6), 10#9, Rc).
+
+%%% main encode dispatch
+
+insn_encode(Op, Opnds) ->
+ case Op of
+ %% I-Form
+ 'b' -> b_AA_LK(Opnds, 0, 0);
+ 'ba' -> b_AA_LK(Opnds, 1, 0);
+ 'bl' -> b_AA_LK(Opnds, 0, 1);
+ 'bla' -> b_AA_LK(Opnds, 1, 1);
+ %% B-Form
+ 'bc' -> bc_AA_LK(Opnds, 0, 0);
+ 'bca' -> bc_AA_LK(Opnds, 1, 0);
+ 'bcl' -> bc_AA_LK(Opnds, 0, 1);
+ 'bcla' -> bc_AA_LK(Opnds, 1, 1);
+ %% SC-Form
+ 'sc' -> sc(Opnds);
+ %% D-Form
+ 'addi' -> addi(Opnds);
+ 'addic' -> addic(Opnds);
+ 'addic.' -> addic_dot(Opnds);
+ 'addis' -> addis(Opnds);
+ 'andi.' -> andi_dot(Opnds);
+ 'andis.' -> andis_dot(Opnds);
+ 'cmpi' -> cmpi(Opnds);
+ 'cmpli' -> cmpli(Opnds);
+ 'lbz' -> lbz(Opnds);
+ 'lbzu' -> lbzu(Opnds);
+ 'lfd' -> lfd(Opnds);
+ 'lfdu' -> lfdu(Opnds);
+ 'lfs' -> lfs(Opnds);
+ 'lfsu' -> lfsu(Opnds);
+ 'lha' -> lha(Opnds);
+ 'lhau' -> lhau(Opnds);
+ 'lhz' -> lhz(Opnds);
+ 'lhzu' -> lhzu(Opnds);
+ 'lmw' -> lmw(Opnds);
+ 'lwz' -> lwz(Opnds);
+ 'lwzu' -> lwzu(Opnds);
+ 'mulli' -> mulli(Opnds);
+ 'ori' -> ori(Opnds);
+ 'oris' -> oris(Opnds);
+ 'stb' -> stb(Opnds);
+ 'stbu' -> stbu(Opnds);
+ 'stfd' -> stfd(Opnds);
+ 'stfdu' -> stfdu(Opnds);
+ 'stfs' -> stfs(Opnds);
+ 'stfsu' -> stfsu(Opnds);
+ 'sth' -> sth(Opnds);
+ 'sthu' -> sthu(Opnds);
+ 'stmw' -> stmw(Opnds);
+ 'stw' -> stw(Opnds);
+ 'stwu' -> stwu(Opnds);
+ 'subfic' -> subfic(Opnds);
+ 'tdi' -> tdi(Opnds);
+ 'twi' -> twi(Opnds);
+ 'xori' -> xori(Opnds);
+ 'xoris' -> xoris(Opnds);
+ %% DS-Form
+ 'ld' -> ld(Opnds);
+ 'ldu' -> ldu(Opnds);
+ 'lwa' -> lwa(Opnds);
+ 'std' -> std(Opnds);
+ 'stdu' -> stdu(Opnds);
+ %% X-Form
+ 'and' -> and_Rc(Opnds, 0);
+ 'and.' -> and_Rc(Opnds, 1);
+ 'andc' -> andc_Rc(Opnds, 0);
+ 'andc.' -> andc_Rc(Opnds, 1);
+ 'cmp' -> cmp(Opnds);
+ 'cmpl' -> cmpl(Opnds);
+ 'cntlzd' -> cntlzd_Rc(Opnds, 0);
+ 'cntlzd.' -> cntlzd_Rc(Opnds, 1);
+ 'cntlzw' -> cntlzw_Rc(Opnds, 0);
+ 'cntlzw.' -> cntlzw_Rc(Opnds, 1);
+ 'dcba' -> dcba(Opnds);
+ 'dcbf' -> dcbf(Opnds);
+ 'dcbi' -> dcbi(Opnds);
+ 'dcbst' -> dcbst(Opnds);
+ 'dcbt' -> dcbt(Opnds);
+ 'dcbtst' -> dcbtst(Opnds);
+ 'dcbz' -> dcbz(Opnds);
+ 'eciwx' -> eciwx(Opnds);
+ 'ecowx' -> ecowx(Opnds);
+ 'eieio' -> eieio(Opnds);
+ 'eqv' -> eqv_Rc(Opnds, 0);
+ 'eqv.' -> eqv_Rc(Opnds, 1);
+ 'extsb' -> extsb_Rc(Opnds, 0);
+ 'extsb.' -> extsb_Rc(Opnds, 1);
+ 'extsh' -> extsh_Rc(Opnds, 0);
+ 'extsh.' -> extsh_Rc(Opnds, 1);
+ 'extsw' -> extsw_Rc(Opnds, 0);
+ 'extsw.' -> extsw_Rc(Opnds, 1);
+ 'fabs' -> fabs_Rc(Opnds, 0);
+ 'fabs.' -> fabs_Rc(Opnds, 1);
+ 'fcfid' -> fcfid_Rc(Opnds, 0);
+ 'fcfid.' -> fcfid_Rc(Opnds, 1);
+ 'fcmpo' -> fcmpo(Opnds);
+ 'fcmpu' -> fcmpu(Opnds);
+ 'fctid' -> fctid_Rc(Opnds, 0);
+ 'fctid.' -> fctid_Rc(Opnds, 1);
+ 'fctidz' -> fctidz_Rc(Opnds, 0);
+ 'fctidz.' -> fctidz_Rc(Opnds, 1);
+ 'fctiw' -> fctiw_Rc(Opnds, 0);
+ 'fctiw.' -> fctiw_Rc(Opnds, 1);
+ 'fctiwz' -> fctiwz_Rc(Opnds, 0);
+ 'fctiwz.' -> fctiwz_Rc(Opnds, 1);
+ 'fmr' -> fmr_Rc(Opnds, 0);
+ 'fmr.' -> fmr_Rc(Opnds, 1);
+ 'fnabs' -> fnabs_Rc(Opnds, 0);
+ 'fnabs.' -> fnabs_Rc(Opnds, 1);
+ 'fneg' -> fneg_Rc(Opnds, 0);
+ 'fneg.' -> fneg_Rc(Opnds, 1);
+ 'frsp' -> frsp_Rc(Opnds, 0);
+ 'frsp.' -> frsp_Rc(Opnds, 1);
+ 'icbi' -> icbi(Opnds);
+ 'lbzux' -> lbzux(Opnds);
+ 'lbzx' -> lbzx(Opnds);
+ 'ldarx' -> ldarx(Opnds);
+ 'ldux' -> ldux(Opnds);
+ 'ldx' -> ldx(Opnds);
+ 'lfdux' -> lfdux(Opnds);
+ 'lfdx' -> lfdx(Opnds);
+ 'lfsux' -> lfsux(Opnds);
+ 'lfsx' -> lfsx(Opnds);
+ 'lhaux' -> lhaux(Opnds);
+ 'lhax' -> lhax(Opnds);
+ 'lhbrx' -> lhbrx(Opnds);
+ 'lhzux' -> lhzux(Opnds);
+ 'lhzx' -> lhzx(Opnds);
+ 'lswi' -> lswi(Opnds);
+ 'lswx' -> lswx(Opnds);
+ 'lwarx' -> lwarx(Opnds);
+ 'lwaux' -> lwaux(Opnds);
+ 'lwax' -> lwax(Opnds);
+ 'lwbrx' -> lwbrx(Opnds);
+ 'lwzux' -> lwzux(Opnds);
+ 'lwzx' -> lwzx(Opnds);
+ 'mcrfs' -> mcrfs(Opnds);
+ %% 'mcrxr' -> mcrxr(Opnds);
+ 'mfcr' -> mfcr(Opnds);
+ 'mffs' -> mffs_Rc(Opnds, 0);
+ 'mffs.' -> mffs_Rc(Opnds, 1);
+ 'mfmsr' -> mfmsr(Opnds);
+ 'mfsr' -> mfsr(Opnds);
+ 'mfsrin' -> mfsrin(Opnds);
+ 'mtfsb0' -> mtfsb0_Rc(Opnds, 0);
+ 'mtfsb0.' -> mtfsb0_Rc(Opnds, 1);
+ 'mtfsb1' -> mtfsb1_Rc(Opnds, 0);
+ 'mtfsb1.' -> mtfsb1_Rc(Opnds, 1);
+ 'mtfsfi' -> mtfsfi_Rc(Opnds, 0);
+ 'mtfsfi.' -> mtfsfi_Rc(Opnds, 1);
+ 'mtmsr' -> mtmsr(Opnds);
+ 'mtmsrd' -> mtmsrd(Opnds);
+ 'mtsr' -> mtsr(Opnds);
+ 'mtsrd' -> mtsrd(Opnds);
+ 'mtsrdin' -> mtsrdin(Opnds);
+ 'mtsrin' -> mtsrin(Opnds);
+ 'nand' -> nand_Rc(Opnds, 0);
+ 'nand.' -> nand_Rc(Opnds, 1);
+ 'nor' -> nor_Rc(Opnds, 0);
+ 'nor.' -> nor_Rc(Opnds, 1);
+ 'or' -> or_Rc(Opnds, 0);
+ 'or.' -> or_Rc(Opnds, 1);
+ 'orc' -> orc_Rc(Opnds, 0);
+ 'orc.' -> orc_Rc(Opnds, 1);
+ 'slbia' -> slbia(Opnds);
+ 'slbie' -> slbie(Opnds);
+ 'sld' -> sld_Rc(Opnds, 0);
+ 'sld.' -> sld_Rc(Opnds, 1);
+ 'slw' -> slw_Rc(Opnds, 0);
+ 'slw.' -> slw_Rc(Opnds, 1);
+ 'srad' -> srad_Rc(Opnds, 0);
+ 'srad.' -> srad_Rc(Opnds, 1);
+ 'sraw' -> sraw_Rc(Opnds, 0);
+ 'sraw.' -> sraw_Rc(Opnds, 1);
+ 'srawi' -> srawi_Rc(Opnds, 0);
+ 'srawi.' -> srawi_Rc(Opnds, 1);
+ 'srd' -> srd_Rc(Opnds, 0);
+ 'srd.' -> srd_Rc(Opnds, 1);
+ 'srw' -> srw_Rc(Opnds, 0);
+ 'srw.' -> srw_Rc(Opnds, 1);
+ 'stbux' -> stbux(Opnds);
+ 'stbx' -> stbx(Opnds);
+ 'stdcx.' -> stdcx_dot(Opnds);
+ 'stdux' -> stdux(Opnds);
+ 'stdx' -> stdx(Opnds);
+ 'stfdux' -> stfdux(Opnds);
+ 'stfdx' -> stfdx(Opnds);
+ 'stfiwx' -> stfiwx(Opnds);
+ 'stfsux' -> stfsux(Opnds);
+ 'stfsx' -> stfsx(Opnds);
+ 'sthbrx' -> sthbrx(Opnds);
+ 'sthux' -> sthux(Opnds);
+ 'sthx' -> sthx(Opnds);
+ 'stswi' -> stswi(Opnds);
+ 'stswx' -> stswx(Opnds);
+ 'stwbrx' -> stwbrx(Opnds);
+ 'stwcx.' -> stwcx_dot(Opnds);
+ 'stwux' -> stwux(Opnds);
+ 'stwx' -> stwx(Opnds);
+ 'sync' -> sync(Opnds);
+ 'td' -> td(Opnds);
+ 'tlbia' -> tlbia(Opnds); % not implemented in MPC603e or MPC7450
+ 'tlbie' -> tlbie(Opnds);
+ 'tlbld' -> tlbld(Opnds);
+ 'tlbli' -> tlbli(Opnds);
+ 'tlbsync' -> tlbsync(Opnds);
+ 'tw' -> tw(Opnds);
+ 'xor' -> xor_Rc(Opnds, 0);
+ 'xor.' -> xor_Rc(Opnds, 1);
+ %% XL-Form
+ 'bcctr' -> bcctr_lk(Opnds, 0);
+ 'bcctrl' -> bcctr_lk(Opnds, 1);
+ 'bclr' -> bclr_lk(Opnds, 0);
+ 'bclrl' -> bclr_lk(Opnds, 1);
+ 'crand' -> crand(Opnds);
+ 'crandc' -> crandc(Opnds);
+ 'creqv' -> creqv(Opnds);
+ 'crnand' -> crnand(Opnds);
+ 'crnor' -> crnor(Opnds);
+ 'cror' -> cror(Opnds);
+ 'crorc' -> crorc(Opnds);
+ 'crxor' -> crxor(Opnds);
+ 'isync' -> isync(Opnds);
+ 'mcrf' -> mcrf(Opnds);
+ 'rfi' -> rfi(Opnds);
+ 'rfid' -> rfid(Opnds);
+ %% XFX-Form
+ 'mfspr' -> mfspr(Opnds);
+ 'mftb' -> mftb(Opnds);
+ 'mtcrf' -> mtcrf(Opnds);
+ 'mtspr' -> mtspr(Opnds);
+ %% XFL-Form
+ 'mtfsf' -> mtfsf_Rc(Opnds, 0);
+ 'mtfsf.' -> mtfsf_Rc(Opnds, 1);
+ %% XS-Form
+ 'sradi' -> sradi_Rc(Opnds, 0);
+ 'sradi.' -> sradi_Rc(Opnds, 1);
+ %% XO-Form
+ 'add' -> add_OE_Rc(Opnds, 0, 0);
+ 'add.' -> add_OE_Rc(Opnds, 0, 1);
+ 'addo' -> add_OE_Rc(Opnds, 1, 0);
+ 'addo.' -> add_OE_Rc(Opnds, 1, 1);
+ 'addc' -> addc_OE_Rc(Opnds, 0, 0);
+ 'addc.' -> addc_OE_Rc(Opnds, 0, 1);
+ 'addco' -> addc_OE_Rc(Opnds, 1, 0);
+ 'addco.' -> addc_OE_Rc(Opnds, 1, 1);
+ 'adde' -> adde_OE_Rc(Opnds, 0, 0);
+ 'adde.' -> adde_OE_Rc(Opnds, 0, 1);
+ 'addeo' -> adde_OE_Rc(Opnds, 1, 0);
+ 'addeo.' -> adde_OE_Rc(Opnds, 1, 1);
+ 'addme' -> addme_OE_Rc(Opnds, 0, 0);
+ 'addme.' -> addme_OE_Rc(Opnds, 0, 1);
+ 'addmeo' -> addme_OE_Rc(Opnds, 1, 0);
+ 'addmeo.' -> addme_OE_Rc(Opnds, 1, 1);
+ 'addze' -> addze_OE_Rc(Opnds, 0, 0);
+ 'addze.' -> addze_OE_Rc(Opnds, 0, 1);
+ 'addzeo' -> addze_OE_Rc(Opnds, 1, 0);
+ 'addzeo.' -> addze_OE_Rc(Opnds, 1, 1);
+ 'divd' -> divd_OE_Rc(Opnds, 0, 0);
+ 'divd.' -> divd_OE_Rc(Opnds, 0, 1);
+ 'divdo' -> divd_OE_Rc(Opnds, 1, 0);
+ 'divdo.' -> divd_OE_Rc(Opnds, 1, 1);
+ 'divdu' -> divdu_OE_Rc(Opnds, 0, 0);
+ 'divdu.' -> divdu_OE_Rc(Opnds, 0, 1);
+ 'divduo' -> divdu_OE_Rc(Opnds, 1, 0);
+ 'divduo.' -> divdu_OE_Rc(Opnds, 1, 1);
+ 'divw' -> divw_OE_Rc(Opnds, 0, 0);
+ 'divw.' -> divw_OE_Rc(Opnds, 0, 1);
+ 'divwo' -> divw_OE_Rc(Opnds, 1, 0);
+ 'divwo.' -> divw_OE_Rc(Opnds, 1, 1);
+ 'divwu' -> divwu_OE_Rc(Opnds, 0, 0);
+ 'divwu.' -> divwu_OE_Rc(Opnds, 0, 1);
+ 'divwuo' -> divwu_OE_Rc(Opnds, 1, 0);
+ 'divwuo.' -> divwu_OE_Rc(Opnds, 1, 1);
+ 'mulhd' -> mulhd_Rc(Opnds, 0);
+ 'mulhd.' -> mulhd_Rc(Opnds, 1);
+ 'mulhdu' -> mulhdu_Rc(Opnds, 0);
+ 'mulhdu.' -> mulhdu_Rc(Opnds, 1);
+ 'mulhw' -> mulhw_Rc(Opnds, 0);
+ 'mulhw.' -> mulhw_Rc(Opnds, 1);
+ 'mulhwu' -> mulhwu_Rc(Opnds, 0);
+ 'mulhwu.' -> mulhwu_Rc(Opnds, 1);
+ 'mulld' -> mulld_OE_Rc(Opnds, 0, 0);
+ 'mulld.' -> mulld_OE_Rc(Opnds, 0, 1);
+ 'mulldo' -> mulld_OE_Rc(Opnds, 1, 0);
+ 'mulldo.' -> mulld_OE_Rc(Opnds, 1, 1);
+ 'mullw' -> mullw_OE_Rc(Opnds, 0, 0);
+ 'mullw.' -> mullw_OE_Rc(Opnds, 0, 1);
+ 'mullwo' -> mullw_OE_Rc(Opnds, 1, 0);
+ 'mullwo.' -> mullw_OE_Rc(Opnds, 1, 1);
+ 'neg' -> neg_OE_Rc(Opnds, 0, 0);
+ 'neg.' -> neg_OE_Rc(Opnds, 0, 1);
+ 'nego' -> neg_OE_Rc(Opnds, 1, 0);
+ 'nego.' -> neg_OE_Rc(Opnds, 1, 1);
+ 'subf' -> subf_OE_Rc(Opnds, 0, 0);
+ 'subf.' -> subf_OE_Rc(Opnds, 0, 1);
+ 'subfo' -> subf_OE_Rc(Opnds, 1, 0);
+ 'subfo.' -> subf_OE_Rc(Opnds, 1, 1);
+ 'subfc' -> subfc_OE_Rc(Opnds, 0, 0);
+ 'subfc.' -> subfc_OE_Rc(Opnds, 0, 1);
+ 'subfco' -> subfc_OE_Rc(Opnds, 1, 0);
+ 'subfco.' -> subfc_OE_Rc(Opnds, 1, 1);
+ 'subfe' -> subfe_OE_Rc(Opnds, 0, 0);
+ 'subfe.' -> subfe_OE_Rc(Opnds, 0, 1);
+ 'subfeo' -> subfe_OE_Rc(Opnds, 1, 0);
+ 'subfeo.' -> subfe_OE_Rc(Opnds, 1, 1);
+ 'subfme' -> subfme_OE_Rc(Opnds, 0, 0);
+ 'subfme.' -> subfme_OE_Rc(Opnds, 0, 1);
+ 'subfmeo' -> subfme_OE_Rc(Opnds, 1, 0);
+ 'subfmeo.' -> subfme_OE_Rc(Opnds, 1, 1);
+ 'subfze' -> subfze_OE_Rc(Opnds, 0, 0);
+ 'subfze.' -> subfze_OE_Rc(Opnds, 0, 1);
+ 'subfzeo' -> subfze_OE_Rc(Opnds, 1, 0);
+ 'subfzeo.' -> subfze_OE_Rc(Opnds, 1, 1);
+ %% A-Form
+ 'fadd' -> fadd_Rc(Opnds, 0);
+ 'fadd.' -> fadd_Rc(Opnds, 1);
+ 'fadds' -> fadds_Rc(Opnds, 0);
+ 'fadds.' -> fadds_Rc(Opnds, 1);
+ 'fdiv' -> fdiv_Rc(Opnds, 0);
+ 'fdiv.' -> fdiv_Rc(Opnds, 1);
+ 'fdivs' -> fdivs_Rc(Opnds, 0);
+ 'fdivs.' -> fdivs_Rc(Opnds, 1);
+ 'fmadd' -> fmadd_Rc(Opnds, 0);
+ 'fmadd.' -> fmadd_Rc(Opnds, 1);
+ 'fmadds' -> fmadds_Rc(Opnds, 0);
+ 'fmadds.' -> fmadds_Rc(Opnds, 1);
+ 'fmsub' -> fmsub_Rc(Opnds, 0);
+ 'fmsub.' -> fmsub_Rc(Opnds, 1);
+ 'fmsubs' -> fmsubs_Rc(Opnds, 0);
+ 'fmsubs.' -> fmsubs_Rc(Opnds, 1);
+ 'fmul' -> fmul_Rc(Opnds, 0);
+ 'fmul.' -> fmul_Rc(Opnds, 1);
+ 'fmuls' -> fmuls_Rc(Opnds, 0);
+ 'fmuls.' -> fmuls_Rc(Opnds, 1);
+ 'fnmadd' -> fnmadd_Rc(Opnds, 0);
+ 'fnmadd.' -> fnmadd_Rc(Opnds, 1);
+ 'fnmadds' -> fnmadds_Rc(Opnds, 0);
+ 'fnmadds.' -> fnmadds_Rc(Opnds, 1);
+ 'fnmsub' -> fnmsub_Rc(Opnds, 0);
+ 'fnmsub.' -> fnmsub_Rc(Opnds, 1);
+ 'fnmsubs' -> fnmsubs_Rc(Opnds, 0);
+ 'fnmsubs.' -> fnmsubs_Rc(Opnds, 1);
+ 'fres' -> fres_Rc(Opnds, 0);
+ 'fres.' -> fres_Rc(Opnds, 1);
+ 'frsqrte' -> frsqrte_Rc(Opnds, 0);
+ 'frsqrte.' -> frsqrte_Rc(Opnds, 1);
+ 'fsel' -> fsel_Rc(Opnds, 0);
+ 'fsel.' -> fsel_Rc(Opnds, 1);
+ 'fsqrt' -> fsqrt_Rc(Opnds, 0); % not implemented in MPC603e or MPC7450
+ 'fsqrt.' -> fsqrt_Rc(Opnds, 1); % not implemented in MPC603e or MPC7450
+ 'fsqrts' -> fsqrts_Rc(Opnds, 0); % not implemented in MPC603e or MPC7450
+ 'fsqrts.' -> fsqrts_Rc(Opnds, 1); % not implemented in MPC603e or MPC7450
+ 'fsub' -> fsub_Rc(Opnds, 0);
+ 'fsub.' -> fsub_Rc(Opnds, 1);
+ 'fsubs' -> fsubs_Rc(Opnds, 0);
+ 'fsubs.' -> fsubs_Rc(Opnds, 1);
+ %% M-Form
+ 'rlwimi' -> rlwimi_Rc(Opnds, 0);
+ 'rlwimi.' -> rlwimi_Rc(Opnds, 1);
+ 'rlwinm' -> rlwinm_Rc(Opnds, 0);
+ 'rlwinm.' -> rlwinm_Rc(Opnds, 1);
+ 'rlwnm' -> rlwnm_Rc(Opnds, 0);
+ 'rlwnm.' -> rlwnm_Rc(Opnds, 1);
+ %% MD-Form
+ 'rldic' -> rldic_Rc(Opnds, 0);
+ 'rldic.' -> rldic_Rc(Opnds, 1);
+ 'rldicl' -> rldicl_Rc(Opnds, 0);
+ 'rldicl.' -> rldicl_Rc(Opnds, 1);
+ 'rldicr' -> rldicr_Rc(Opnds, 0);
+ 'rldicr.' -> rldicr_Rc(Opnds, 1);
+ 'rldimi' -> rldimi_Rc(Opnds, 0);
+ 'rldimi.' -> rldimi_Rc(Opnds, 1);
+ %% MDS-Form
+ 'rldcl' -> rldcl(Opnds, 0);
+ 'rldcl.' -> rldcl(Opnds, 1);
+ 'rldcr' -> rldcr(Opnds, 0);
+ 'rldcr.' -> rldcr(Opnds, 1);
+ _ -> exit({?MODULE,insn_encode,Op})
+ end.
+
+%%% testing interface
+
+-ifdef(TESTING).
+
+say(OS, Str) ->
+ file:write(OS, Str).
+
+hex_digit(Dig0) ->
+ Dig = Dig0 band 16#F,
+ if Dig >= 16#A -> $A + (Dig - 16#A);
+ true -> $0 + Dig
+ end.
+
+say_byte(OS, Byte) ->
+ say(OS, [hex_digit(Byte bsr 4)]),
+ say(OS, [hex_digit(Byte)]).
+
+say_word(OS, Word) ->
+ say(OS, "0x"),
+ say_byte(OS, Word bsr 24),
+ say_byte(OS, Word bsr 16),
+ say_byte(OS, Word bsr 8),
+ say_byte(OS, Word).
+
+t(OS, Op, Opnds) ->
+ Word = insn_encode(Op, Opnds),
+ say(OS, "\t.long "),
+ say_word(OS, Word),
+ say(OS, "\n").
+
+dotest1(OS) ->
+ say(OS, "\t.text\n\t.align 4\n"),
+ %%
+ R14 = {r,14},
+ R10 = {r,10},
+ R11 = {r,11},
+ F2 = {fr,2},
+ F4 = {fr,4},
+ F6 = {fr,6},
+ F8 = {fr,8},
+ DispM3 = {d,16#FFFD},
+ DS = {ds,16#FFFD bsr 2},
+ SIMM99 = {simm,10#99},
+ UIMM4711 = {uimm,10#4711},
+ TO_LLE = {to, 2#00110}, % =, <U
+ CR7 = {crf,7},
+ CR5 = {crf,5},
+ CRB_CR0_LT = {crb,0},
+ CRB_CR7_SO = {crb,31},
+ CRB_CR1_GT = {crb,5},
+ CRM192 = {crm,192},
+ FM255 = {fm,16#FF}, % all fields
+ CRIMM15 = {crimm,16#F},
+ TBR268 = {tbr, 10#268}, % TBL
+ SPR9 = {spr, 10#9}, % CTR
+ SR9 = {sr,9},
+ NB7 = {nb,7},
+ SH16 = {sh,16},
+ SH45 = {sh6,45},
+ MB10 = {mb,10},
+ MB40 = {mb6,40},
+ ME20 = {me,20},
+ ME50 = {me6,50},
+ LI = {li,16#ffffff},
+ BD = {bd,16#3ff},
+ BO_NZ_PLUS = {bo,2#01101}, % branch if cond true, predict taken
+ BI_CR0_EQ = {bi,2#00010}, % CR0[2], Zero
+ %% I-Form
+ t(OS,'b',{LI}),
+ t(OS,'ba',{LI}),
+ t(OS,'bl',{LI}),
+ t(OS,'bla',{LI}),
+ %% B-Form
+ t(OS,'bc',{BO_NZ_PLUS,BI_CR0_EQ,BD}),
+ t(OS,'bca',{BO_NZ_PLUS,BI_CR0_EQ,BD}),
+ t(OS,'bcl',{BO_NZ_PLUS,BI_CR0_EQ,BD}),
+ t(OS,'bcla',{BO_NZ_PLUS,BI_CR0_EQ,BD}),
+ %% SC-Form
+ t(OS,'sc',{}),
+ %% D-Form
+ t(OS,'addi',{R14,R10,SIMM99}),
+ t(OS,'addic',{R14,R10,SIMM99}),
+ t(OS,'addic.',{R14,R10,SIMM99}),
+ t(OS,'addis',{R14,R10,SIMM99}),
+ t(OS,'andi.',{R14,R10,UIMM4711}),
+ t(OS,'andis.',{R14,R10,UIMM4711}),
+ t(OS,'cmpi',{CR7,0,R10,SIMM99}),
+ t(OS,'cmpi',{CR7,1,R10,SIMM99}),
+ t(OS,'cmpli',{CR7,0,R10,UIMM4711}),
+ t(OS,'cmpli',{CR7,1,R10,UIMM4711}),
+ t(OS,'lbz',{R14,DispM3,R10}),
+ t(OS,'lbzu',{R14,DispM3,R10}),
+ t(OS,'lfd',{F2,DispM3,R10}),
+ t(OS,'lfdu',{F2,DispM3,R10}),
+ t(OS,'lfs',{F2,DispM3,R10}),
+ t(OS,'lfsu',{F2,DispM3,R10}),
+ t(OS,'lha',{R14,DispM3,R10}),
+ t(OS,'lhau',{R14,DispM3,R10}),
+ t(OS,'lhz',{R14,DispM3,R10}),
+ t(OS,'lhzu',{R14,DispM3,R10}),
+ t(OS,'lmw',{R14,DispM3,R10}),
+ t(OS,'lwz',{R14,DispM3,R10}),
+ t(OS,'lwzu',{R14,DispM3,R10}),
+ t(OS,'mulli',{R14,R10,SIMM99}),
+ t(OS,'ori',{R14,R10,UIMM4711}),
+ t(OS,'oris',{R14,R10,UIMM4711}),
+ t(OS,'stb',{R14,DispM3,R10}),
+ t(OS,'stbu',{R14,DispM3,R10}),
+ t(OS,'stfd',{F2,DispM3,R10}),
+ t(OS,'stfdu',{F2,DispM3,R10}),
+ t(OS,'stfs',{F2,DispM3,R10}),
+ t(OS,'stfsu',{F2,DispM3,R10}),
+ t(OS,'sth',{R14,DispM3,R10}),
+ t(OS,'sthu',{R14,DispM3,R10}),
+ t(OS,'stmw',{R14,DispM3,R10}),
+ t(OS,'stw',{R14,DispM3,R10}),
+ t(OS,'stwu',{R14,DispM3,R10}),
+ t(OS,'subfic',{R14,R10,SIMM99}),
+ t(OS,'tdi',{TO_LLE,R10,SIMM99}),
+ t(OS,'twi',{TO_LLE,R10,SIMM99}),
+ t(OS,'xori',{R14,R10,UIMM4711}),
+ t(OS,'xoris',{R14,R10,UIMM4711}),
+ %% DS-Form
+ t(OS,'ld',{R14,DS,R10}),
+ t(OS,'ldu',{R14,DS,R10}),
+ t(OS,'lwa',{R14,DS,R10}),
+ t(OS,'std',{R14,DS,R10}),
+ t(OS,'stdu',{R14,DS,R10}),
+ %% X-Form
+ t(OS,'and',{R14,R10,R11}),
+ t(OS,'and.',{R14,R10,R11}),
+ t(OS,'andc',{R14,R10,R11}),
+ t(OS,'andc.',{R14,R10,R11}),
+ t(OS,'cmp',{CR7,0,R10,R11}),
+ t(OS,'cmp',{CR7,1,R10,R11}),
+ t(OS,'cmpl',{CR7,0,R10,R11}),
+ t(OS,'cmpl',{CR7,1,R10,R11}),
+ t(OS,'cntlzd',{R14,R10}),
+ t(OS,'cntlzd.',{R14,R10}),
+ t(OS,'cntlzw',{R14,R10}),
+ t(OS,'cntlzw.',{R14,R10}),
+ t(OS,'dcba',{R10,R11}),
+ t(OS,'dcbf',{R10,R11}),
+ t(OS,'dcbi',{R10,R11}),
+ t(OS,'dcbst',{R10,R11}),
+ t(OS,'dcbt',{R10,R11}),
+ t(OS,'dcbtst',{R10,R11}),
+ t(OS,'dcbz',{R10,R11}),
+ t(OS,'eciwx',{R14,R10,R11}),
+ t(OS,'ecowx',{R14,R10,R11}),
+ t(OS,'eieio',{}),
+ t(OS,'eqv',{R14,R10,R11}),
+ t(OS,'eqv.',{R14,R10,R11}),
+ t(OS,'extsb',{R14,R10}),
+ t(OS,'extsb.',{R14,R10}),
+ t(OS,'extsh',{R14,R10}),
+ t(OS,'extsh.',{R14,R10}),
+ t(OS,'extsw',{R14,R10}),
+ t(OS,'extsw.',{R14,R10}),
+ t(OS,'fabs',{F2,F8}),
+ t(OS,'fabs.',{F2,F8}),
+ t(OS,'fcfid',{F2,F8}),
+ t(OS,'fcfid.',{F2,F8}),
+ t(OS,'fcmpo',{CR7,F4,F8}),
+ t(OS,'fcmpu',{CR7,F4,F8}),
+ t(OS,'fctid',{F2,F8}),
+ t(OS,'fctid.',{F2,F8}),
+ t(OS,'fctidz',{F2,F8}),
+ t(OS,'fctidz.',{F2,F8}),
+ t(OS,'fctiw',{F2,F8}),
+ t(OS,'fctiw.',{F2,F8}),
+ t(OS,'fctiwz',{F2,F8}),
+ t(OS,'fctiwz.',{F2,F8}),
+ t(OS,'fmr',{F2,F8}),
+ t(OS,'fmr.',{F2,F8}),
+ t(OS,'fnabs',{F2,F8}),
+ t(OS,'fnabs.',{F2,F8}),
+ t(OS,'fneg',{F2,F8}),
+ t(OS,'fneg.',{F2,F8}),
+ t(OS,'frsp',{F2,F8}),
+ t(OS,'frsp.',{F2,F8}),
+ t(OS,'icbi',{R10,R11}),
+ t(OS,'lbzux',{R14,R10,R11}),
+ t(OS,'lbzx',{R14,R10,R11}),
+ t(OS,'ldarx',{R14,R10,R11}),
+ t(OS,'ldux',{R14,R10,R11}),
+ t(OS,'ldx',{R14,R10,R11}),
+ t(OS,'lfdux',{F2,R10,R11}),
+ t(OS,'lfdx',{F2,R10,R11}),
+ t(OS,'lfsux',{F2,R10,R11}),
+ t(OS,'lfsx',{F2,R10,R11}),
+ t(OS,'lhaux',{R14,R10,R11}),
+ t(OS,'lhax',{R14,R10,R11}),
+ t(OS,'lhbrx',{R14,R10,R11}),
+ t(OS,'lhzux',{R14,R10,R11}),
+ t(OS,'lhzx',{R14,R10,R11}),
+ t(OS,'lswi',{R14,R10,NB7}),
+ t(OS,'lswx',{R14,R10,R11}),
+ t(OS,'lwarx',{R14,R10,R11}),
+ t(OS,'lwaux',{R14,R10,R11}),
+ t(OS,'lwax',{R14,R10,R11}),
+ t(OS,'lwbrx',{R14,R10,R11}),
+ t(OS,'lwzux',{R14,R10,R11}),
+ t(OS,'lwzx',{R14,R10,R11}),
+ t(OS,'mcrfs',{CR7,CR5}),
+ %% t(OS,'mcrxr',{CR7}),
+ t(OS,'mfcr',{R14}),
+ t(OS,'mffs',{F2}),
+ t(OS,'mffs.',{F2}),
+ t(OS,'mfmsr',{R14}),
+ t(OS,'mfsr',{R14,SR9}),
+ t(OS,'mfsrin',{R14,R11}),
+ t(OS,'mtfsb0',{CRB_CR0_LT}),
+ t(OS,'mtfsb0.',{CRB_CR0_LT}),
+ t(OS,'mtfsb1',{CRB_CR0_LT}),
+ t(OS,'mtfsb1.',{CRB_CR0_LT}),
+ t(OS,'mtfsfi',{CR7,CRIMM15}),
+ t(OS,'mtfsfi.',{CR7,CRIMM15}),
+ t(OS,'mtmsr',{R14}),
+ t(OS,'mtmsrd',{R14}),
+ t(OS,'mtsr',{SR9,R14}),
+ t(OS,'mtsrd',{SR9,R14}),
+ t(OS,'mtsrdin',{R14,R11}),
+ t(OS,'mtsrin',{R14,R11}),
+ t(OS,'nand',{R14,R10,R11}),
+ t(OS,'nand.',{R14,R10,R11}),
+ t(OS,'nor',{R14,R10,R11}),
+ t(OS,'nor.',{R14,R10,R11}),
+ t(OS,'or',{R14,R10,R11}),
+ t(OS,'or.',{R14,R10,R11}),
+ t(OS,'orc',{R14,R10,R11}),
+ t(OS,'orc.',{R14,R10,R11}),
+ t(OS,'slbia',{}),
+ t(OS,'slbie',{R11}),
+ t(OS,'sld',{R14,R10,R11}),
+ t(OS,'sld.',{R14,R10,R11}),
+ t(OS,'slw',{R14,R10,R11}),
+ t(OS,'slw.',{R14,R10,R11}),
+ t(OS,'srad',{R14,R10,R11}),
+ t(OS,'srad.',{R14,R10,R11}),
+ t(OS,'sraw',{R14,R10,R11}),
+ t(OS,'sraw.',{R14,R10,R11}),
+ t(OS,'srawi',{R14,R10,SH16}),
+ t(OS,'srawi.',{R14,R10,SH16}),
+ t(OS,'srd',{R14,R10,R11}),
+ t(OS,'srd.',{R14,R10,R11}),
+ t(OS,'srw',{R14,R10,R11}),
+ t(OS,'srw.',{R14,R10,R11}),
+ t(OS,'stbux',{R14,R10,R11}),
+ t(OS,'stbx',{R14,R10,R11}),
+ t(OS,'stdcx.',{R14,R10,R11}),
+ t(OS,'stdux',{R14,R10,R11}),
+ t(OS,'stdx',{R14,R10,R11}),
+ t(OS,'stfdux',{F2,R10,R11}),
+ t(OS,'stfdx',{F2,R10,R11}),
+ t(OS,'stfiwx',{F2,R10,R11}),
+ t(OS,'stfsux',{F2,R10,R11}),
+ t(OS,'stfsx',{F2,R10,R11}),
+ t(OS,'sthbrx',{R14,R10,R11}),
+ t(OS,'sthux',{R14,R10,R11}),
+ t(OS,'sthx',{R14,R10,R11}),
+ t(OS,'stswi',{R14,R10,NB7}),
+ t(OS,'stswx',{R14,R10,R11}),
+ t(OS,'stwbrx',{R14,R10,R11}),
+ t(OS,'stwcx.',{R14,R10,R11}),
+ t(OS,'stwux',{R14,R10,R11}),
+ t(OS,'stwx',{R14,R10,R11}),
+ t(OS,'sync',{}),
+ t(OS,'td',{TO_LLE,R10,R11}),
+ t(OS,'tlbia',{}),
+ t(OS,'tlbie',{R11}),
+ t(OS,'tlbld',{R11}),
+ t(OS,'tlbli',{R11}),
+ t(OS,'tlbsync',{}),
+ t(OS,'tw',{TO_LLE,R10,R11}),
+ t(OS,'xor',{R14,R10,R11}),
+ t(OS,'xor.',{R14,R10,R11}),
+ %% XL-Form
+ t(OS,'bcctr',{BO_NZ_PLUS,BI_CR0_EQ}),
+ t(OS,'bcctrl',{BO_NZ_PLUS,BI_CR0_EQ}),
+ t(OS,'bclr',{BO_NZ_PLUS,BI_CR0_EQ}),
+ t(OS,'bclrl',{BO_NZ_PLUS,BI_CR0_EQ}),
+ t(OS,'crand',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'crandc',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'creqv',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'crnand',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'crnor',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'cror',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'crorc',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'crxor',{CRB_CR0_LT,CRB_CR7_SO,CRB_CR1_GT}),
+ t(OS,'isync',{}),
+ t(OS,'mcrf',{CR7,CR5}),
+ t(OS,'rfi',{}),
+ t(OS,'rfid',{}),
+ %% XFX-Form
+ t(OS,'mfspr',{R14,SPR9}),
+ t(OS,'mftb',{R14,TBR268}),
+ t(OS,'mtcrf',{CRM192,R14}),
+ t(OS,'mtspr',{SPR9,R14}),
+ %% XFL-Form
+ t(OS,'mtfsf',{FM255,F8}),
+ t(OS,'mtfsf.',{FM255,F8}),
+ %% XS-Form
+ t(OS,'sradi',{R14,R10,SH45}),
+ t(OS,'sradi.',{R14,R10,SH45}),
+ %% XO-Form
+ t(OS,'add',{R14,R10,R11}),
+ t(OS,'add.',{R14,R10,R11}),
+ t(OS,'addo',{R14,R10,R11}),
+ t(OS,'addo.',{R14,R10,R11}),
+ t(OS,'addc',{R14,R10,R11}),
+ t(OS,'addc.',{R14,R10,R11}),
+ t(OS,'addco',{R14,R10,R11}),
+ t(OS,'addco.',{R14,R10,R11}),
+ t(OS,'adde',{R14,R10,R11}),
+ t(OS,'adde.',{R14,R10,R11}),
+ t(OS,'addeo',{R14,R10,R11}),
+ t(OS,'addeo.',{R14,R10,R11}),
+ t(OS,'addme',{R14,R10}),
+ t(OS,'addme.',{R14,R10}),
+ t(OS,'addmeo',{R14,R10}),
+ t(OS,'addmeo.',{R14,R10}),
+ t(OS,'addze',{R14,R10}),
+ t(OS,'addze.',{R14,R10}),
+ t(OS,'addzeo',{R14,R10}),
+ t(OS,'addzeo.',{R14,R10}),
+ t(OS,'divd',{R14,R10,R11}),
+ t(OS,'divd.',{R14,R10,R11}),
+ t(OS,'divdo',{R14,R10,R11}),
+ t(OS,'divdo.',{R14,R10,R11}),
+ t(OS,'divdu',{R14,R10,R11}),
+ t(OS,'divdu.',{R14,R10,R11}),
+ t(OS,'divduo',{R14,R10,R11}),
+ t(OS,'divduo.',{R14,R10,R11}),
+ t(OS,'divw',{R14,R10,R11}),
+ t(OS,'divw.',{R14,R10,R11}),
+ t(OS,'divwo',{R14,R10,R11}),
+ t(OS,'divwo.',{R14,R10,R11}),
+ t(OS,'divwu',{R14,R10,R11}),
+ t(OS,'divwu.',{R14,R10,R11}),
+ t(OS,'divwuo',{R14,R10,R11}),
+ t(OS,'divwuo.',{R14,R10,R11}),
+ t(OS,'mulhd',{R14,R10,R11}),
+ t(OS,'mulhd.',{R14,R10,R11}),
+ t(OS,'mulhdu',{R14,R10,R11}),
+ t(OS,'mulhdu.',{R14,R10,R11}),
+ t(OS,'mulhw',{R14,R10,R11}),
+ t(OS,'mulhw.',{R14,R10,R11}),
+ t(OS,'mulhwu',{R14,R10,R11}),
+ t(OS,'mulhwu.',{R14,R10,R11}),
+ t(OS,'mulld',{R14,R10,R11}),
+ t(OS,'mulld.',{R14,R10,R11}),
+ t(OS,'mulldo',{R14,R10,R11}),
+ t(OS,'mulldo.',{R14,R10,R11}),
+ t(OS,'mullw',{R14,R10,R11}),
+ t(OS,'mullw.',{R14,R10,R11}),
+ t(OS,'mullwo',{R14,R10,R11}),
+ t(OS,'mullwo.',{R14,R10,R11}),
+ t(OS,'neg',{R14,R10}),
+ t(OS,'neg.',{R14,R10}),
+ t(OS,'nego',{R14,R10}),
+ t(OS,'nego.',{R14,R10}),
+ t(OS,'subf',{R14,R10,R11}),
+ t(OS,'subf.',{R14,R10,R11}),
+ t(OS,'subfo',{R14,R10,R11}),
+ t(OS,'subfo.',{R14,R10,R11}),
+ t(OS,'subfc',{R14,R10,R11}),
+ t(OS,'subfc.',{R14,R10,R11}),
+ t(OS,'subfco',{R14,R10,R11}),
+ t(OS,'subfco.',{R14,R10,R11}),
+ t(OS,'subfe',{R14,R10,R11}),
+ t(OS,'subfe.',{R14,R10,R11}),
+ t(OS,'subfeo',{R14,R10,R11}),
+ t(OS,'subfeo.',{R14,R10,R11}),
+ t(OS,'subfme',{R14,R10}),
+ t(OS,'subfme.',{R14,R10}),
+ t(OS,'subfmeo',{R14,R10}),
+ t(OS,'subfmeo.',{R14,R10}),
+ t(OS,'subfze',{R14,R10}),
+ t(OS,'subfze.',{R14,R10}),
+ t(OS,'subfzeo',{R14,R10}),
+ t(OS,'subfzeo.',{R14,R10}),
+ %% A-Form
+ t(OS,'fadd',{F2,F4,F8}),
+ t(OS,'fadd.',{F2,F4,F8}),
+ t(OS,'fadds',{F2,F4,F8}),
+ t(OS,'fadds.',{F2,F4,F8}),
+ t(OS,'fdiv',{F2,F4,F8}),
+ t(OS,'fdiv.',{F2,F4,F8}),
+ t(OS,'fdivs',{F2,F4,F8}),
+ t(OS,'fdivs.',{F2,F4,F8}),
+ t(OS,'fmadd',{F2,F4,F6,F8}),
+ t(OS,'fmadd.',{F2,F4,F6,F8}),
+ t(OS,'fmadds',{F2,F4,F6,F8}),
+ t(OS,'fmadds.',{F2,F4,F6,F8}),
+ t(OS,'fmsub',{F2,F4,F6,F8}),
+ t(OS,'fmsub.',{F2,F4,F6,F8}),
+ t(OS,'fmsubs',{F2,F4,F6,F8}),
+ t(OS,'fmsubs.',{F2,F4,F6,F8}),
+ t(OS,'fmul',{F2,F4,F6}),
+ t(OS,'fmul.',{F2,F4,F6}),
+ t(OS,'fmuls',{F2,F4,F6}),
+ t(OS,'fmuls.',{F2,F4,F6}),
+ t(OS,'fnmadd',{F2,F4,F6,F8}),
+ t(OS,'fnmadd.',{F2,F4,F6,F8}),
+ t(OS,'fnmadds',{F2,F4,F6,F8}),
+ t(OS,'fnmadds.',{F2,F4,F6,F8}),
+ t(OS,'fnmsub',{F2,F4,F6,F8}),
+ t(OS,'fnmsub.',{F2,F4,F6,F8}),
+ t(OS,'fnmsubs',{F2,F4,F6,F8}),
+ t(OS,'fnmsubs.',{F2,F4,F6,F8}),
+ t(OS,'fres',{F2,F8}),
+ t(OS,'fres.',{F2,F8}),
+ t(OS,'frsqrte',{F2,F8}),
+ t(OS,'frsqrte.',{F2,F8}),
+ t(OS,'fsel',{F2,F4,F6,F8}),
+ t(OS,'fsel.',{F2,F4,F6,F8}),
+ t(OS,'fsqrt',{F2,F8}),
+ t(OS,'fsqrt.',{F2,F8}),
+ t(OS,'fsqrts',{F2,F8}),
+ t(OS,'fsqrts.',{F2,F8}),
+ t(OS,'fsub',{F2,F4,F8}),
+ t(OS,'fsub.',{F2,F4,F8}),
+ t(OS,'fsubs',{F2,F4,F8}),
+ t(OS,'fsubs.',{F2,F4,F8}),
+ %% M-Form
+ t(OS,'rlwimi',{R14,R10,SH16,MB10,ME20}),
+ t(OS,'rlwimi.',{R14,R10,SH16,MB10,ME20}),
+ t(OS,'rlwinm',{R14,R10,SH16,MB10,ME20}),
+ t(OS,'rlwinm.',{R14,R10,SH16,MB10,ME20}),
+ t(OS,'rlwnm',{R14,R10,R11,MB10,ME20}),
+ t(OS,'rlwnm.',{R14,R10,R11,MB10,ME20}),
+ %% MD-Form
+ t(OS,'rldic',{R14,R10,SH45,MB40}),
+ t(OS,'rldic.',{R14,R10,SH45,MB40}),
+ t(OS,'rldicl',{R14,R10,SH45,MB40}),
+ t(OS,'rldicl.',{R14,R10,SH45,MB40}),
+ t(OS,'rldicr',{R14,R10,SH45,ME50}),
+ t(OS,'rldicr.',{R14,R10,SH45,ME50}),
+ t(OS,'rldimi',{R14,R10,SH45,MB40}),
+ t(OS,'rldimi.',{R14,R10,SH45,MB40}),
+ %% MDS-Form
+ t(OS,'rldcl',{R14,R10,R11,MB40}),
+ t(OS,'rldcl.',{R14,R10,R11,MB40}),
+ t(OS,'rldcr',{R14,R10,R11,ME50}),
+ t(OS,'rldcr.',{R14,R10,R11,ME50}),
+ [].
+
+dotest() -> dotest1(group_leader()).
+
+dotest(File) ->
+ {ok,OS} = file:open(File, [write]),
+ dotest1(OS),
+ file:close(OS).
+
+-endif.