From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/hipe/ppc/hipe_ppc_encode.erl | 1558 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1558 insertions(+) create mode 100644 lib/hipe/ppc/hipe_ppc_encode.erl (limited to 'lib/hipe/ppc/hipe_ppc_encode.erl') 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}, % =, dotest1(group_leader()). + +dotest(File) -> + {ok,OS} = file:open(File, [write]), + dotest1(OS), + file:close(OS). + +-endif. -- cgit v1.2.3