1%% -*- erlang-indent-level: 2 -*- 2%% 3%% Licensed under the Apache License, Version 2.0 (the "License"); 4%% you may not use this file except in compliance with the License. 5%% You may obtain a copy of the License at 6%% 7%% http://www.apache.org/licenses/LICENSE-2.0 8%% 9%% Unless required by applicable law or agreed to in writing, software 10%% distributed under the License is distributed on an "AS IS" BASIS, 11%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12%% See the License for the specific language governing permissions and 13%% limitations under the License. 14 15-module(hipe_ppc_pp). 16-export([pp/1, pp/2, pp_insn/1]). 17 18-include("hipe_ppc.hrl"). 19 20pp(Defun) -> 21 pp(standard_io, Defun). 22 23pp(Dev, #defun{mfa={M,F,A}, code=Code, data=Data}) -> 24 Fname = atom_to_list(M)++"_"++atom_to_list(F)++"_"++integer_to_list(A), 25 io:format(Dev, "\t.text\n", []), 26 io:format(Dev, "\t.align 4\n", []), 27 io:format(Dev, "\t.global ~s\n", [Fname]), 28 io:format(Dev, "~s:\n", [Fname]), 29 pp_insns(Dev, Code, Fname), 30 io:format(Dev, "\t.rodata\n", []), 31 io:format(Dev, "\t.align 4\n", []), 32 hipe_data_pp:pp(Dev, Data, ppc, Fname), 33 io:format(Dev, "\n", []). 34 35pp_insns(Dev, [I|Is], Fname) -> 36 pp_insn(Dev, I, Fname), 37 pp_insns(Dev, Is, Fname); 38pp_insns(_, [], _) -> 39 []. 40 41pp_insn(I) -> 42 pp_insn(standard_io, I, ""). 43 44pp_insn(Dev, I, Pre) -> 45 case I of 46 #alu{aluop=AluOp, dst=Dst, src1=Src1, src2=Src2} -> 47 io:format(Dev, "\t~s ", [alu_op_name(AluOp)]), 48 pp_temp(Dev, Dst), 49 io:format(Dev, ", ", []), 50 pp_temp(Dev, Src1), 51 io:format(Dev, ", ", []), 52 pp_src(Dev, Src2), 53 io:format(Dev, "\n", []); 54 #b_fun{'fun'=Fun, linkage=Linkage} -> 55 io:format(Dev, "\tb ", []), 56 pp_fun(Dev, Fun), 57 io:format(Dev, " # ~w\n", [Linkage]); 58 #b_label{label=Label} -> 59 io:format(Dev, "\tb .~s_~w\n", [Pre, Label]); 60 #bc{bcond=BCond, label=Label, pred=Pred} -> 61 io:format(Dev, "\tb~w ~s_~w # ~.2f\n", [bcond_name(BCond), Pre, Label, Pred]); 62 #bctr{labels=Labels} -> 63 io:format(Dev, "\tbctr", []), 64 case Labels of 65 [] -> []; 66 _ -> 67 io:format(Dev, " #", []), 68 pp_labels(Dev, Labels, Pre) 69 end, 70 io:format(Dev, "\n", []); 71 #bctrl{sdesc=SDesc} -> 72 io:format(Dev, "\tbctrl #", []), 73 pp_sdesc(Dev, Pre, SDesc), 74 io:format(Dev, "\n", []); 75 #bl{'fun'=Fun, sdesc=SDesc, linkage=Linkage} -> 76 io:format(Dev, "\tbl ", []), 77 pp_fun(Dev, Fun), 78 io:format(Dev, " #", []), 79 pp_sdesc(Dev, Pre, SDesc), 80 io:format(Dev, " ~w\n", [Linkage]); 81 #blr{} -> 82 io:format(Dev, "\tblr\n", []); 83 #comment{term=Term} -> 84 io:format(Dev, "\t# ~p\n", [Term]); 85 #cmp{cmpop=CmpOp, src1=Src1, src2=Src2} -> 86 io:format(Dev, "\t~s ", [cmp_op_name(CmpOp)]), 87 pp_temp(Dev, Src1), 88 io:format(Dev, ", ", []), 89 pp_src(Dev, Src2), 90 io:format(Dev, "\n", []); 91 #label{label=Label} -> 92 io:format(Dev, ".~s_~w:~n", [Pre, Label]); 93 #load{ldop=LdOp, dst=Dst, disp=Disp, base=Base} -> 94 io:format(Dev, "\t~w ", [ldop_name(LdOp)]), 95 pp_temp(Dev, Dst), 96 io:format(Dev, ", ~s(", [to_hex(Disp)]), 97 pp_temp(Dev, Base), 98 io:format(Dev, ")\n", []); 99 #loadx{ldxop=LdxOp, dst=Dst, base1=Base1, base2=Base2} -> 100 io:format(Dev, "\t~w ", [ldxop_name(LdxOp)]), 101 pp_temp(Dev, Dst), 102 io:format(Dev, ", ", []), 103 pp_temp(Dev, Base1), 104 io:format(Dev, ", ", []), 105 pp_temp(Dev, Base2), 106 io:format(Dev, "\n", []); 107 #mfspr{dst=Dst, spr=SPR} -> 108 io:format(Dev, "\tmf~w ", [spr_name(SPR)]), 109 pp_temp(Dev, Dst), 110 io:format(Dev, "\n", []); 111 #mtcr{src=Src} -> 112 io:format(Dev, "\tmtcrf 0x80, ", []), 113 pp_temp(Dev, Src), 114 io:format(Dev, "\n", []); 115 #mtspr{spr=SPR, src=Src} -> 116 io:format(Dev, "\tmt~w ", [spr_name(SPR)]), 117 pp_temp(Dev, Src), 118 io:format(Dev, "\n", []); 119 #pseudo_bc{bcond=BCond, true_label=TrueLab, false_label=FalseLab, pred=Pred} -> 120 io:format(Dev, "\tpseudo_bc ~w, .~s_~w # .~s_~w ~.2f\n", 121 [bcond_name(BCond), Pre, TrueLab, Pre, FalseLab, Pred]); 122 #pseudo_call{func=FunC, sdesc=SDesc, contlab=ContLab, linkage=Linkage} -> 123 io:format(Dev, "\tpseudo_call ", []), 124 pp_func(Dev, FunC), 125 io:format(Dev, " # contlab .~s_~w", [Pre, ContLab]), 126 pp_sdesc(Dev, Pre, SDesc), 127 io:format(Dev, " ~w\n", [Linkage]); 128 #pseudo_call_prepare{nrstkargs=NrStkArgs} -> 129 SP = hipe_ppc_registers:reg_name_gpr(hipe_ppc_registers:stack_pointer()), 130 io:format(Dev, "\taddi ~s, ~s, ~w # pseudo_call_prepare\n", 131 [SP, SP, -(4*NrStkArgs)]); 132 #pseudo_li{dst=Dst, imm=Imm} -> 133 io:format(Dev, "\tpseudo_li ", []), 134 pp_temp(Dev, Dst), 135 io:format(Dev, ", ", []), 136 pp_imm(Dev, Imm), 137 io:format(Dev, "\n", []); 138 #pseudo_move{dst=Dst, src=Src} -> 139 io:format(Dev, "\tpseudo_move ", []), 140 pp_temp(Dev, Dst), 141 io:format(Dev, ", ", []), 142 pp_temp(Dev, Src), 143 io:format(Dev, "\n", []); 144 #pseudo_tailcall{func=FunC, arity=Arity, stkargs=StkArgs, linkage=Linkage} -> 145 io:format(Dev, "\tpseudo_tailcall ", []), 146 pp_func(Dev, FunC), 147 io:format(Dev, "/~w (", [Arity]), 148 pp_args(Dev, StkArgs), 149 io:format(Dev, ") ~w\n", [Linkage]); 150 #pseudo_tailcall_prepare{} -> 151 io:format(Dev, "\tpseudo_tailcall_prepare\n", []); 152 #store{stop=StOp, src=Src, disp=Disp, base=Base} -> 153 io:format(Dev, "\t~s ", [stop_name(StOp)]), 154 pp_temp(Dev, Src), 155 io:format(Dev, ", ~s(", [to_hex(Disp)]), 156 pp_temp(Dev, Base), 157 io:format(Dev, ")\n", []); 158 #storex{stxop=StxOp, src=Src, base1=Base1, base2=Base2} -> 159 io:format(Dev, "\t~s ", [stxop_name(StxOp)]), 160 pp_temp(Dev, Src), 161 io:format(Dev, ", ", []), 162 pp_temp(Dev, Base1), 163 io:format(Dev, ", ", []), 164 pp_temp(Dev, Base2), 165 io:format(Dev, "\n", []); 166 #unary{unop={UnOp,I1,I2,I3}, dst=Dst, src=Src} -> 167 io:format(Dev, "\t~s ", [UnOp]), 168 pp_temp(Dev, Dst), 169 io:format(Dev, ", ", []), 170 pp_temp(Dev, Src), 171 io:format(Dev, ", ~s, ~s, ~s\n", [to_hex(I1),to_hex(I2),to_hex(I3)]); 172 #unary{unop=UnOp, dst=Dst, src=Src} -> 173 io:format(Dev, "\t~w ", [unop_name(UnOp)]), 174 pp_temp(Dev, Dst), 175 io:format(Dev, ", ", []), 176 pp_temp(Dev, Src), 177 io:format(Dev, "\n", []); 178 #lfd{dst=Dst, disp=Disp, base=Base} -> 179 io:format(Dev, "\tlfd ", []), 180 pp_temp(Dev, Dst), 181 io:format(Dev, ", ~s(", [to_hex(Disp)]), 182 pp_temp(Dev, Base), 183 io:format(Dev, ")\n", []); 184 #lfdx{dst=Dst, base1=Base1, base2=Base2} -> 185 io:format(Dev, "\tlfdx ", []), 186 pp_temp(Dev, Dst), 187 io:format(Dev, ", ", []), 188 pp_temp(Dev, Base1), 189 io:format(Dev, ", ", []), 190 pp_temp(Dev, Base2), 191 io:format(Dev, "\n", []); 192 #stfd{src=Src, disp=Disp, base=Base} -> 193 io:format(Dev, "\tstfd ", []), 194 pp_temp(Dev, Src), 195 io:format(Dev, ", ~s(", [to_hex(Disp)]), 196 pp_temp(Dev, Base), 197 io:format(Dev, ")\n", []); 198 #stfdx{src=Src, base1=Base1, base2=Base2} -> 199 io:format(Dev, "\tstfdx ", []), 200 pp_temp(Dev, Src), 201 io:format(Dev, ", ", []), 202 pp_temp(Dev, Base1), 203 io:format(Dev, ", ", []), 204 pp_temp(Dev, Base2), 205 io:format(Dev, "\n", []); 206 #fp_binary{fp_binop=FpBinOp, dst=Dst, src1=Src1, src2=Src2} -> 207 io:format(Dev, "\t~s ", [FpBinOp]), 208 pp_temp(Dev, Dst), 209 io:format(Dev, ", ", []), 210 pp_temp(Dev, Src1), 211 io:format(Dev, ", ", []), 212 pp_temp(Dev, Src2), 213 io:format(Dev, "\n", []); 214 #fp_unary{fp_unop=FpUnOp, dst=Dst, src=Src} -> 215 io:format(Dev, "\t~s ", [FpUnOp]), 216 pp_temp(Dev, Dst), 217 io:format(Dev, ", ", []), 218 pp_temp(Dev, Src), 219 io:format(Dev, "\n", []); 220 #pseudo_fmove{dst=Dst, src=Src} -> 221 io:format(Dev, "\tpseudo_fmove ", []), 222 pp_temp(Dev, Dst), 223 io:format(Dev, ", ", []), 224 pp_temp(Dev, Src), 225 io:format(Dev, "\n", []); 226 _ -> 227 exit({?MODULE, pp_insn, I}) 228 end. 229 230to_hex(N) -> 231 io_lib:format("~.16x", [N, "0x"]). 232 233pp_sdesc(Dev, Pre, #ppc_sdesc{exnlab=ExnLab,fsize=FSize,arity=Arity,live=Live}) -> 234 pp_sdesc_exnlab(Dev, Pre, ExnLab), 235 io:format(Dev, " ~s ~w [", [to_hex(FSize), Arity]), 236 pp_sdesc_live(Dev, Live), 237 io:format(Dev, "]", []). 238 239pp_sdesc_exnlab(Dev, _, []) -> io:format(Dev, " []", []); 240pp_sdesc_exnlab(Dev, Pre, ExnLab) -> io:format(Dev, " .~s_~w", [Pre, ExnLab]). 241 242pp_sdesc_live(_, {}) -> []; 243pp_sdesc_live(Dev, Live) -> pp_sdesc_live(Dev, Live, 1). 244 245pp_sdesc_live(Dev, Live, I) -> 246 io:format(Dev, "~s", [to_hex(element(I, Live))]), 247 if I < tuple_size(Live) -> 248 io:format(Dev, ",", []), 249 pp_sdesc_live(Dev, Live, I+1); 250 true -> [] 251 end. 252 253pp_labels(Dev, [Label|Labels], Pre) -> 254 io:format(Dev, " .~s_~w", [Pre, Label]), 255 pp_labels(Dev, Labels, Pre); 256pp_labels(_, [], _) -> 257 []. 258 259pp_fun(Dev, Fun) -> 260 case Fun of 261 #ppc_mfa{m=M, f=F, a=A} -> 262 io:format(Dev, "~w:~w/~w", [M, F, A]); 263 #ppc_prim{prim=Prim} -> 264 io:format(Dev, "~w", [Prim]) 265 end. 266 267pp_func(Dev, FunC) -> 268 case FunC of 269 'ctr' -> 270 io:format(Dev, "ctr", []); 271 Fun -> 272 pp_fun(Dev, Fun) 273 end. 274 275alu_op_name(Op) -> Op. 276 277bcond_name(BCond) -> BCond. 278 279cmp_op_name(Op) -> Op. 280 281spr_name(SPR) -> SPR. 282 283ldop_name(LdOp) -> LdOp. 284 285ldxop_name(LdxOp) -> LdxOp. 286 287stop_name(StOp) -> StOp. 288 289stxop_name(StxOp) -> StxOp. 290 291unop_name(UnOp) -> UnOp. 292 293pp_temp(Dev, Temp=#ppc_temp{reg=Reg, type=Type}) -> 294 case hipe_ppc:temp_is_precoloured(Temp) of 295 true -> 296 Name = 297 case Type of 298 'double' -> hipe_ppc_registers:reg_name_fpr(Reg); 299 _ -> hipe_ppc_registers:reg_name_gpr(Reg) 300 end, 301 io:format(Dev, "~s", [Name]); 302 false -> 303 Tag = 304 case Type of 305 double -> "f"; 306 tagged -> "t"; 307 untagged -> "u" 308 end, 309 io:format(Dev, "~s~w", [Tag, Reg]) 310 end. 311 312pp_hex(Dev, Value) -> io:format(Dev, "~s", [to_hex(Value)]). 313pp_simm16(Dev, #ppc_simm16{value=Value}) -> pp_hex(Dev, Value). 314pp_uimm16(Dev, #ppc_uimm16{value=Value}) -> pp_hex(Dev, Value). 315 316pp_imm(Dev, Value) -> 317 if is_integer(Value) -> pp_hex(Dev, Value); 318 true -> io:format(Dev, "~w", [Value]) 319 end. 320 321pp_src(Dev, Src) -> 322 case Src of 323 #ppc_temp{} -> 324 pp_temp(Dev, Src); 325 #ppc_simm16{} -> 326 pp_simm16(Dev, Src); 327 #ppc_uimm16{} -> 328 pp_uimm16(Dev, Src) 329 end. 330 331pp_arg(Dev, Arg) -> 332 case Arg of 333 #ppc_temp{} -> 334 pp_temp(Dev, Arg); 335 _ -> 336 pp_hex(Dev, Arg) 337 end. 338 339pp_args(Dev, [A|As]) -> 340 pp_arg(Dev, A), 341 pp_comma_args(Dev, As); 342pp_args(_, []) -> 343 []. 344 345pp_comma_args(Dev, [A|As]) -> 346 io:format(Dev, ", ", []), 347 pp_arg(Dev, A), 348 pp_comma_args(Dev, As); 349pp_comma_args(_, []) -> 350 []. 351