aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/sparc/hipe_sparc_encode.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/sparc/hipe_sparc_encode.erl')
-rw-r--r--lib/hipe/sparc/hipe_sparc_encode.erl476
1 files changed, 476 insertions, 0 deletions
diff --git a/lib/hipe/sparc/hipe_sparc_encode.erl b/lib/hipe/sparc/hipe_sparc_encode.erl
new file mode 100644
index 0000000000..8a28f33ab9
--- /dev/null
+++ b/lib/hipe/sparc/hipe_sparc_encode.erl
@@ -0,0 +1,476 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%
+%%% %CopyrightBegin%
+%%%
+%%% Copyright Ericsson AB 2007-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 SPARC instructions to binary form.
+%%% Copyright (C) 2007-2008 Mikael Pettersson
+
+-module(hipe_sparc_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).
+
+bf(LeftBit, RightBit, Value) ->
+ ?ASSERT(32 > LeftBit),
+ ?ASSERT(LeftBit >= RightBit),
+ ?ASSERT(RightBit >= 0),
+ ?ASSERT(Value >= 0),
+ ?ASSERT(Value < (1 bsl ((LeftBit - RightBit) + 1))),
+ Value bsl RightBit.
+
+-define(BF(LB,RB,V), bf(LB,RB,V)).
+-define(BIT(Pos,Val), ?BF(Pos,Pos,Val)).
+%%-define(BITS(N,Val), ?BF(N,0,Val)).
+
+%%%
+%%% Instruction Formats
+%%%
+
+format1(Disp30) ->
+ ?BIT(30,1) bor ?BF(29,0,Disp30).
+
+format2a(Rd, Op2, Imm22) ->
+ ?BF(29,25,Rd) bor ?BF(24,22,Op2) bor ?BF(21,0,Imm22).
+
+format2b(A, Cond, Op2, Disp22) ->
+ ?BIT(29,A) bor ?BF(28,25,Cond) bor ?BF(24,22,Op2) bor ?BF(21,0,Disp22).
+
+format2c(A, Cond, Op2, CC1, CC0, P, Disp19) ->
+ ?BIT(29,A) bor ?BF(28,25,Cond) bor ?BF(24,22,Op2) bor ?BIT(21,CC1)
+ bor ?BIT(20,CC0) bor ?BIT(19,P) bor ?BF(18,0,Disp19).
+
+format2d(A, RCond, Op2, P, Rs1, Disp16) ->
+ D16Hi = Disp16 bsr 14,
+ D16Lo = Disp16 band 16#3FFF,
+ ?BIT(29,A) bor ?BF(27,25,RCond) bor ?BF(24,22,Op2) bor ?BF(21,20,D16Hi)
+ bor ?BIT(19,P) bor ?BF(18,14,Rs1) bor ?BF(13,0,D16Lo).
+
+format3common(Op, Rd, Op3, Rs1) -> % format 3, bits 31..14
+ ?BF(31,30,Op) bor ?BF(29,25,Rd) bor ?BF(24,19,Op3) bor ?BF(18,14,Rs1).
+
+format3a(Op, Rd, Op3, Rs1, Rs2) ->
+ format3common(Op, Rd, Op3, Rs1) bor ?BF(4,0,Rs2).
+
+format3ax(Op, Rd, Op3, Rs1, Rs2) ->
+ format3a(Op, Rd, Op3, Rs1, Rs2) bor ?BIT(12,1).
+
+format3b(Op, Rd, Op3, Rs1, Simm13) ->
+ format3common(Op, Rd, Op3, Rs1) bor ?BIT(13,1) bor ?BF(12,0,Simm13).
+
+format3b32(Op, Rd, Op3, Rs1, Shcnt32) ->
+ format3a(Op, Rd, Op3, Rs1, Shcnt32) bor ?BIT(13,1).
+
+format3b64(Op, Rd, Op3, Rs1, Shcnt64) ->
+ format3common(Op, Rd, Op3, Rs1) bor ?BIT(13,1) bor ?BF(5,0,Shcnt64).
+
+format3ab(Op, {r,Rd}, Op3, {r,Rs1}, Src2) ->
+ case Src2 of
+ {r,Rs2} ->
+ format3a(Op, Rd, Op3, Rs1, Rs2);
+ {simm13,Simm13} ->
+ format3b(Op, Rd, Op3, Rs1, Simm13)
+ end.
+
+format3ab({Rs1,Src2,Rd}, Op3, Op) -> format3ab(Op, Rd, Op3, Rs1, Src2).
+
+-ifdef(notdef).
+format3c(Op, Rd, Op3, Rs1, Opf, Rs2) ->
+ format3h(Op, Rd, Op3, Rs1) bor (Opf bsl 5) bor Rs2.
+
+format3d(Op, Rd, Op3, Rs1, I, Rs2) ->
+ format3h(Op, Rd, Op3, Rs1) bor (I bsl 13) bor Rs2.
+-endif.
+
+%%%
+%%% Instruction Operands
+%%%
+
+'cond'(Cond) ->
+ case Cond of
+ 'n' -> 2#0000;
+ 'e' -> 2#0001;
+ 'le' -> 2#0010;
+ 'l' -> 2#0011;
+ 'leu' -> 2#0100;
+ 'lu' -> 2#0101; % a.k.a. 'cs'
+ 'neg' -> 2#0110;
+ 'vs' -> 2#0111;
+ 'a' -> 2#1000;
+ 'ne' -> 2#1001;
+ 'g' -> 2#1010;
+ 'ge' -> 2#1011;
+ 'gu' -> 2#1100;
+ 'geu' -> 2#1101; % a.k.a. 'cc'
+ 'pos' -> 2#1110;
+ 'vc' -> 2#1111
+ end.
+
+rcond(RCond) ->
+ case RCond of
+ 'z' -> 2#001;
+ 'lez' -> 2#010;
+ 'lz' -> 2#011;
+ 'nz' -> 2#101;
+ 'gz' -> 2#110;
+ 'gez' -> 2#111
+ end.
+
+pred(Pred) ->
+ case Pred of
+ 'pt' -> 1;
+ 'pn' -> 0
+ end.
+
+%%%
+%%% Branch Instructions
+%%%
+
+call({disp30,Disp30}) ->
+ format1(Disp30).
+
+ba({disp22,Disp22}) -> % V7 Bicc, only used for unconditional branches
+ format2b(0, 'cond'('a'), 2#010, Disp22).
+
+bp({{'cond',Cond},{pred,Pred},{disp19,Disp19}}) ->
+ %% XXX: sparc64 will need CC1=1 here
+ format2c(0, 'cond'(Cond), 2#001, 0, 0, pred(Pred), Disp19).
+
+br({{rcond,RCond},{pred,Pred},{r,Rs1},{disp16,Disp16}}) ->
+ format2d(0, rcond(RCond), 2#011, pred(Pred), Rs1, Disp16).
+
+%%%
+%%% Integer Arithmetic Instructions
+%%%
+
+alu(Opnds, Op3) -> format3ab(Opnds, Op3, 2#10).
+
+add(Opnds) -> alu(Opnds, 2#000000).
+addcc(Opnds) -> alu(Opnds, 2#010000).
+%%addc(Opnds) -> alu(Opnds, 2#001000).
+%%addccc(Opnds) -> alu(Opnds, 2#011000).
+
+sub(Opnds) -> alu(Opnds, 2#000100).
+subcc(Opnds) -> alu(Opnds, 2#010100).
+%%subc(Opnds) -> alu(Opnds, 2#001100). % XXX: hipe_sparc_op has bug here
+%%subccc(Opnds) -> alu(Opnds, 2#011100). % XXX: hipe_sparc_op has bug here
+
+%%taddcc(Opnds) -> alu(Opnds, 2#100000).
+%%taddcctv(Opnds) -> alu(Opnds, 2#100010).
+
+%%tsubcc(Opnds) -> alu(Opnds, 2#100001).
+%%tsubcctv(Opnds) -> alu(Opnds, 2#100011).
+
+mulx(Opnds) -> alu(Opnds, 2#001001).
+%%sdivx(Opnds) -> alu(Opnds, 2#101101).
+%%udivx(Opnds) -> alu(Opnds, 2#001101).
+
+%%umul(Opnds) -> alu(Opnds, 2#001010).
+smul(Opnds) -> alu(Opnds, 2#001011).
+%%umulcc(Opnds) -> alu(Opnds, 2#011010).
+%%smulcc(Opnds) -> alu(Opnds, 2#011011).
+
+'and'(Opnds) -> alu(Opnds, 2#000001).
+andcc(Opnds) -> alu(Opnds, 2#010001).
+%%andn(Opnds) -> alu(Opnds, 2#000101).
+%%andncc(Opnds) -> alu(Opnds, 2#010101).
+
+'or'(Opnds) -> alu(Opnds, 2#000010).
+orcc(Opnds) -> alu(Opnds, 2#010010).
+%%orn(Opnds) -> alu(Opnds, 2#000110).
+%%orncc(Opnds) -> alu(Opnds, 2#010110).
+
+'xor'(Opnds) -> alu(Opnds, 2#000011).
+xorcc(Opnds) -> alu(Opnds, 2#010011).
+%%xnor(Opnds) -> alu(Opnds, 2#000111).
+%%xnorcc(Opnds) -> alu(Opnds, 2#010111).
+
+shift32({{r,Rs1},Src2,{r,Rd}}, Op3) ->
+ case Src2 of
+ {r,Rs2} ->
+ format3a(2#10, Rd, Op3, Rs1, Rs2);
+ {uimm5,Shcnt32} ->
+ format3b32(2#10, Rd, Op3, Rs1, Shcnt32)
+ end.
+
+shift64({{r,Rs1},Src2,{r,Rd}}, Op3) ->
+ case Src2 of
+ {r,Rs2} ->
+ format3ax(2#10, Rd, Op3, Rs1, Rs2);
+ {uimm6,Shcnt64} ->
+ format3b64(2#10, Rd, Op3, Rs1, Shcnt64)
+ end.
+
+sll(Opnds) -> shift32(Opnds, 2#100101).
+sllx(Opnds) -> shift64(Opnds, 2#100101).
+srl(Opnds) -> shift32(Opnds, 2#100110).
+srlx(Opnds) -> shift64(Opnds, 2#100110).
+sra(Opnds) -> shift32(Opnds, 2#100111).
+srax(Opnds) -> shift64(Opnds, 2#100111).
+
+jmpl(Opnds) -> alu(Opnds, 2#111000).
+
+rd({y,{r,Rd}}) -> format3a(2#10, Rd, 2#101000, 0, 0).
+
+sethi({{uimm22,UImm22},{r,Rd}}) -> format2a(Rd, 2#100, UImm22).
+
+ld(Opnds, Op3) -> format3ab(Opnds, Op3, 2#11).
+
+ldsb(Opnds) -> ld(Opnds, 2#001001).
+ldsh(Opnds) -> ld(Opnds, 2#001010).
+ldsw(Opnds) -> ld(Opnds, 2#001000).
+ldub(Opnds) -> ld(Opnds, 2#000001).
+lduh(Opnds) -> ld(Opnds, 2#000010).
+lduw(Opnds) -> ld(Opnds, 2#000000).
+ldx(Opnds) -> ld(Opnds, 2#001011).
+%%ldd(Opnds) -> ld(Opnds, 2#000011).
+
+st({Rd,Rs1,Src2}, Op3) -> format3ab(2#11, Rd, Op3, Rs1, Src2).
+
+stb(Opnds) -> st(Opnds, 2#000101).
+%%sth(Opnds) -> st(Opnds, 2#000110).
+stw(Opnds) -> st(Opnds, 2#000100).
+stx(Opnds) -> st(Opnds, 2#001110).
+%%std(Opnds) -> st(Opnds, 2#000111).
+
+%%%
+%%% Floating-Point Instructions
+%%%
+
+format3f(Rd, Rs1, Opf, Rs2) ->
+ format3a(2#10, Rd, 2#110100, Rs1, Rs2) bor ?BF(13,5,Opf).
+
+fpop1binary(Opf, {{fr,Rs1},{fr,Rs2},{fr,Rd}}) ->
+ format3f(Rd, Rs1, Opf, Rs2).
+
+faddd(Opnds) -> fpop1binary(2#001000010, Opnds).
+fdivd(Opnds) -> fpop1binary(2#001001110, Opnds).
+fmuld(Opnds) -> fpop1binary(2#001001010, Opnds).
+fsubd(Opnds) -> fpop1binary(2#001000110, Opnds).
+
+fpop1unary(Opf, {{fr,Rs2},{fr,Rd}}) ->
+ format3f(Rd, 0, Opf, Rs2).
+
+fitod(Opnds) -> fpop1unary(2#011001000, Opnds).
+fmovd(Opnds) -> fpop1unary(2#000000010, Opnds).
+fnegd(Opnds) -> fpop1unary(2#000000110, Opnds).
+
+ldf({{r,Rs1},{simm13,Simm13},{fr,Rd}}) ->
+ format3b(2#11, Rd, 2#100000, Rs1, Simm13).
+
+stf({{fr,Rd},{r,Rs1},{simm13,Simm13}}) ->
+ format3b(2#11, Rd, 2#100100, Rs1, Simm13).
+
+-ifdef(notdef).
+fpop1(Rs1,Opf,Rs2,Rd) -> format3a(2#10, Rd, 2#110100, Rs1, Opf, Rs2).
+%% fpop2(Rs1,Opf,Rs2,Rd) -> format3a(2#10, Rd, 2#110101, Rs1, Opf, Rs2).
+
+%% fxtos(Rs2, Rd) -> fpop1(0,2#010000100,Rs2,Rd).
+%% fxtod(Rs2, Rd) -> fpop1(0,2#010001000,Rs2,Rd).
+%% fxtoq(Rs2, Rd) -> fpop1(0,2#010001100,Rs2,Rd).
+fitos(Rs2, Rd) -> fpop1(0,2#011000100,Rs2,Rd).
+fitoq(Rs2, Rd) -> fpop1(0,2#011001100,Rs2,Rd).
+
+%% fstox(Rs2, Rd) -> fpop1(0,2#010000001,Rs2,Rd).
+%% fdtox(Rs2, Rd) -> fpop1(0,2#010000010,Rs2,Rd).
+%% fqtox(Rs2, Rd) -> fpop1(0,2#010000011,Rs2,Rd).
+%% fstoi(Rs2, Rd) -> fpop1(0,2#011010001,Rs2,Rd).
+%% fdtoi(Rs2, Rd) -> fpop1(0,2#011010010,Rs2,Rd).
+%% fqtoi(Rs2, Rd) -> fpop1(0,2#011010011,Rs2,Rd).
+
+%% fstod(Rs2, Rd) -> fpop1(0,2#011001001,Rs2,Rd).
+%% fstoq(Rs2, Rd) -> fpop1(0,2#011001101,Rs2,Rd).
+%% fdtos(Rs2, Rd) -> fpop1(0,2#011000110,Rs2,Rd).
+%% fdtoq(Rs2, Rd) -> fpop1(0,2#011001110,Rs2,Rd).
+%% fqtos(Rs2, Rd) -> fpop1(0,2#011000111,Rs2,Rd).
+%% fqtod(Rs2, Rd) -> fpop1(0,2#011001011,Rs2,Rd).
+
+fmovs(Rs2, Rd) -> fpop1(0,2#000000001,Rs2,Rd).
+fnegs(Rs2, Rd) -> fpop1(0,2#000000101,Rs2,Rd).
+fabss(Rs2, Rd) -> fpop1(0,2#000001001,Rs2,Rd).
+fabsd(Rs2, Rd) -> fpop1(0,2#000001010,Rs2,Rd).
+fmovq(Rs2, Rd) -> fpop1(0,2#000000011,Rs2,Rd).
+fnegq(Rs2, Rd) -> fpop1(0,2#000000111,Rs2,Rd).
+fabsq(Rs2, Rd) -> fpop1(0,2#000001011,Rs2,Rd).
+
+%% fsqrts(Rs2, Rd) -> fpop1(0,2#000101001,Rs2,Rd).
+%% fsqrtd(Rs2, Rd) -> fpop1(0,2#000101010,Rs2,Rd).
+%% fsqrtq(Rs2, Rd) -> fpop1(0,2#000101011,Rs2,Rd).
+
+fadds(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001000001,Rs2,Rd).
+faddq(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001000011,Rs2,Rd).
+fsubs(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001000101,Rs2,Rd).
+fsubq(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001000111,Rs2,Rd).
+
+fmuls(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001001001,Rs2,Rd).
+fmulq(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001001011,Rs2,Rd).
+%% fsmuld(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001101001,Rs2,Rd).
+%% fdmulq(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001101110,Rs2,Rd).
+fdivs(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001001101,Rs2,Rd).
+fdivq(Rs1, Rs2, Rd) -> fpop1(Rs1,2#001001111,Rs2,Rd).
+
+%% Uses fcc0
+%% fcmps(Rs1, Rs2) -> fpop2(Rs1,2#001010001,Rs2,0).
+%% fcmpd(Rs1, Rs2) -> fpop2(Rs1,2#001010010,Rs2,0).
+%% fcmpq(Rs1, Rs2) -> fpop2(Rs1,2#001010011,Rs2,0).
+%% fcmpes(Rs1, Rs2) -> fpop2(Rs1,2#001010101,Rs2,0).
+%% fcmped(Rs1, Rs2) -> fpop2(Rs1,2#001010110,Rs2,0).
+%% fcmpeq(Rs1, Rs2) -> fpop2(Rs1,2#001010111,Rs2,0).
+
+%% fcmps(N, Rs1, Rs2) -> fpcn(N,2#001010001,Rs1,Rs2).
+%% fcmpd(N, Rs1, Rs2) -> fpcn(N,2#001010010,Rs1,Rs2).
+%% fcmpq(N, Rs1, Rs2) -> fpcn(N,2#001010011,Rs1,Rs2).
+%% fcmpes(N, Rs1, Rs2) -> fpcn(N,2#001010101,Rs1,Rs2).
+%% fcmped(N, Rs1, Rs2) -> fpcn(N,2#001010110,Rs1,Rs2).
+%% fcmpeq(N, Rs1, Rs2) -> fpcn(N,2#001010111,Rs1,Rs2).
+
+stfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100100, Rs1, Offset).
+stdf(Rd, Rs1, Rs2) -> format3a(2#11, Rd, 2#100111, Rs1, 0, Rs2).
+stdfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100111, Rs1, Offset).
+stqf(Rd, Rs1, Rs2) -> format3a(2#11, Rd, 2#100110, Rs1, 0, Rs2).
+stqfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100110, Rs1, Offset).
+%% stfsr(Rd, Rs1, Rs2) -> format3a(2#11, Rd, 2#100101, Rs1, 0, Rs2).
+%% stfsri(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100101, Rs1, Offset).
+
+ldfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100000, Rs1, Offset).
+lddf(Rd, Rs1, Rs2) -> format3a(2#11, Rd, 2#100011, Rs1, 0, Rs2).
+lddfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100011, Rs1, Offset).
+ldqf(Rd, Rs1, Rs2) -> format3a(2#11, Rd, 2#100010, Rs1, 0, Rs2).
+ldqfi(Rd, Rs1, Offset) -> format3b(2#11, Rd, 2#100010, Rs1, Offset).
+%% ldxfsr(Rs1, Rs2) -> format3a(2#11, 1, 2#100001, Rs1, 0, Rs2).
+%% ldxfsri(Rs1, Offset) -> format3b(2#11, 1, 2#100001, Rs1, Offset).
+
+%% fpcn(N, Opf, Rs1, Rs2) ->
+%% case N of
+%% 0 -> fpc0(Opf, Rs1, Rs2);
+%% 1 -> fpc1(Opf, Rs1, Rs2);
+%% 2 -> fpc2(Opf, Rs1, Rs2);
+%% 3 -> fpc3(Opf, Rs1, Rs2)
+%% end.
+
+%% fpc0(Opf, Rs1, Rs2) -> format3c(2#10, 2#00000, 2#110101, Rs1, Opf, Rs2).
+%% fpc1(Opf, Rs1, Rs2) -> format3c(2#10, 2#00001, 2#110101, Rs1, Opf, Rs2).
+%% fpc2(Opf, Rs1, Rs2) -> format3c(2#10, 2#00010, 2#110101, Rs1, Opf, Rs2).
+%% fpc3(Opf, Rs1, Rs2) -> format3c(2#10, 2#00011, 2#110101, Rs1, Opf, Rs2).
+-endif. % FP insns
+
+%%%
+%%% Main Encode Dispatch
+%%%
+
+insn_encode(Op, Opnds) ->
+ case Op of
+ 'add' -> add(Opnds);
+ 'addcc' -> addcc(Opnds);
+ 'and' -> 'and'(Opnds);
+ 'andcc' -> andcc(Opnds);
+ 'ba' -> ba(Opnds);
+ 'bp' -> bp(Opnds);
+ 'br' -> br(Opnds);
+ 'call' -> call(Opnds);
+ 'jmpl' -> jmpl(Opnds);
+ 'ldsb' -> ldsb(Opnds);
+ 'ldsh' -> ldsh(Opnds);
+ 'ldsw' -> ldsw(Opnds);
+ 'ldub' -> ldub(Opnds);
+ 'lduh' -> lduh(Opnds);
+ 'lduw' -> lduw(Opnds);
+ 'ldx' -> ldx(Opnds);
+ 'mulx' -> mulx(Opnds);
+ 'or' -> 'or'(Opnds);
+ 'orcc' -> orcc(Opnds);
+ 'rd' -> rd(Opnds);
+ 'sethi' -> sethi(Opnds);
+ 'sll' -> sll(Opnds);
+ 'sllx' -> sllx(Opnds);
+ 'smul' -> smul(Opnds);
+ 'sra' -> sra(Opnds);
+ 'srax' -> srax(Opnds);
+ 'srl' -> srl(Opnds);
+ 'srlx' -> srlx(Opnds);
+ 'stb' -> stb(Opnds);
+ 'stw' -> stw(Opnds);
+ 'stx' -> stx(Opnds);
+ 'sub' -> sub(Opnds);
+ 'subcc' -> subcc(Opnds);
+ 'xor' -> 'xor'(Opnds);
+ 'xorcc' -> xorcc(Opnds);
+ 'faddd' -> faddd(Opnds);
+ 'fdivd' -> fdivd(Opnds);
+ 'fmuld' -> fmuld(Opnds);
+ 'fsubd' -> fsubd(Opnds);
+ 'fitod' -> fitod(Opnds);
+ 'fmovd' -> fmovd(Opnds);
+ 'fnegd' -> fnegd(Opnds);
+ 'ldf' -> ldf(Opnds);
+ 'stf' -> stf(Opnds);
+ _ -> 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"),
+ [].
+
+dotest() -> dotest1(group_leader()).
+
+dotest(File) ->
+ {ok,OS} = file:open(File, [write]),
+ dotest1(OS),
+ file:close(OS).
+
+-endif.