## translate-machcode-to-execode-pwrpc32-g.codemade.pkg
#
# This file generated at 2015-12-06:08:43:06 by
#
#
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-execode-xxx-g-package.pkg#
# from the architecture description file
#
# src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description
#
# Edits to this file will be LOST on next system rebuild.
# Compiled by:
#
src/lib/compiler/back/low/pwrpc32/backend-pwrpc32.lib# We are invoked from:
#
#
src/lib/compiler/back/low/main/pwrpc32/backend-lowhalf-pwrpc32.pkg#
stipulate
package lbl = codelabel; # codelabel is from
src/lib/compiler/back/low/code/codelabel.pkg package lem = lowhalf_error_message; # lowhalf_error_message is from
src/lib/compiler/back/low/control/lowhalf-error-message.pkg package rkj = registerkinds_junk; # registerkinds_junk is from
src/lib/compiler/back/low/code/registerkinds-junk.pkg package u32 = one_word_unt; # one_word_unt is from
src/lib/std/one-word-unt.pkgherein
generic package translate_machcode_to_execode_pwrpc32_g (
#
package mcf: Machcode_Pwrpc32; # Machcode_Pwrpc32 is from
src/lib/compiler/back/low/pwrpc32/code/machcode-pwrpc32.codemade.api
package tce: Treecode_Eval # Treecode_Eval is from
src/lib/compiler/back/low/treecode/treecode-eval.api where
tcf == mcf::tcf; # "tcf" == "treecode_form".
package cst: Codebuffer; # Codebuffer is from
src/lib/compiler/back/low/code/codebuffer.api
package csb: Code_Segment_Buffer; # Code_Segment_Buffer is from
src/lib/compiler/execution/code-segments/code-segment-buffer.api )
: (weak) Machcode_Codebuffer
{
# Machcode_Codebuffer is from
src/lib/compiler/back/low/emit/machcode-codebuffer.api # Export to client packages:
#
package cst = cst;
package mcf = mcf; # "mcf" == "machcode_form" (abstract machine code).
# Local abbreviations:
#
package rgk = mcf::rgk; # "rgk" == "registerkinds".
package lac = mcf::lac; # "lac" == "late_constant".
package csb = csb;
package pop = cst::pop;
# PWRPC32 is big endian.
fun error msg
=
lem::error ("PWRPC32MC", msg);
fun make_codebuffer _
=
{ infix my &
| << >> >>> ;
#
(<<) = u32::(<<);
(>>) = u32::(>>);
(>>>) = u32::(>>>);
(
|) = u32::bitwise_or;
(&) = u32::bitwise_and;
fun put_bool FALSE => 0u0: u32::Unt;
put_bool TRUE => 0u1: u32::Unt;
end;
put_int = u32::from_int;
fun put_word w = w;
fun put_label l = u32::from_int (lbl::get_codelabel_address l);
fun put_label_expression le = u32::from_int (tce::value_of le);
fun put_const lateconst = u32::from_int (lac::late_constant_to_int lateconst);
loc = REF 0;
# Emit a byte:
#
fun put_byte byte
=
{ offset = *loc;
loc := offset + 1;
csb::write_byte_to_code_segment_buffer { offset, byte };
};
# Emit the low order byte of a word.
# Note: from_large_unt strips the high order bits!
#
fun put_byte_w word
=
{ offset = *loc;
loc := offset + 1;
csb::write_byte_to_code_segment_buffer { offset, byte => one_byte_unt::from_large_unt word };
};
fun do_nothing _ = ();
fun fail _ = raise exception DIE "MCEmitter";
fun get_notes () = error "get_notes";
fun put_pseudo_op pseudo_op
=
pop::put_pseudo_op { pseudo_op, loc => *loc, put_byte };
fun start_new_cccomponent size_in_bytes
=
{ csb::initialize_code_segment_buffer { size_in_bytes };
loc := 0;
};
fun e_word32 w
=
{ b8 = w;
w = w >> 0ux8;
b16 = w;
w = w >> 0ux8;
b24 = w;
w = w >> 0ux8;
b32 = w;
{ put_byte_w b32;
put_byte_w b24;
put_byte_w b16;
put_byte_w b8;
};
};
fun put_int_register r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_float_register r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_flags_register r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_ram_byte r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_control_dependency r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_spr r
=
u32::from_int (rkj::hardware_register_id_of r)
also
fun put_registerset r
=
u32::from_int (rkj::hardware_register_id_of r);
fun put_operand (mcf::REG_OP int_register) => put_int_register int_register;
put_operand (mcf::IMMED_OP int) => u32::from_int int;
put_operand (mcf::LABEL_OP label_expression) => u32::from_int (tce::value_of label_expression);
end
also
fun put_fcmp (mcf::FCMPO) => (0ux20 : one_word_unt::Unt);
put_fcmp (mcf::FCMPU) => (0ux0 : one_word_unt::Unt);
end
also
fun put_unary (mcf::NEG) => (0ux68 : one_word_unt::Unt);
put_unary (mcf::EXTSB) => (0ux3BA : one_word_unt::Unt);
put_unary (mcf::EXTSH) => (0ux39A : one_word_unt::Unt);
put_unary (mcf::EXTSW) => (0ux3DA : one_word_unt::Unt);
put_unary (mcf::CNTLZW) => (0ux1A : one_word_unt::Unt);
put_unary (mcf::CNTLZD) => (0ux3A : one_word_unt::Unt);
end
also
fun put_funary (mcf::FMR) => (0ux3F, 0ux48);
put_funary (mcf::FNEG) => (0ux3F, 0ux28);
put_funary (mcf::FABS) => (0ux3F, 0ux108);
put_funary (mcf::FNABS) => (0ux3F, 0ux88);
put_funary (mcf::FSQRT) => (0ux3F, 0ux16);
put_funary (mcf::FSQRTS) => (0ux3B, 0ux16);
put_funary (mcf::FRSP) => (0ux3F, 0uxC);
put_funary (mcf::FCTIW) => (0ux3F, 0uxE);
put_funary (mcf::FCTIWZ) => (0ux3F, 0uxF);
put_funary (mcf::FCTID) => (0ux3F, 0ux32E);
put_funary (mcf::FCTIDZ) => (0ux3F, 0ux32F);
put_funary (mcf::FCFID) => (0ux3F, 0ux34E);
end
also
fun put_farith (mcf::FADD) => (0ux3F, 0ux15);
put_farith (mcf::FSUB) => (0ux3F, 0ux14);
put_farith (mcf::FMUL) => (0ux3F, 0ux19);
put_farith (mcf::FDIV) => (0ux3F, 0ux12);
put_farith (mcf::FADDS) => (0ux3B, 0ux15);
put_farith (mcf::FSUBS) => (0ux3B, 0ux14);
put_farith (mcf::FMULS) => (0ux3B, 0ux19);
put_farith (mcf::FDIVS) => (0ux3B, 0ux12);
end
also
fun put_farith3 (mcf::FMADD) => (0ux3F, 0ux1D);
put_farith3 (mcf::FMADDS) => (0ux3B, 0ux1D);
put_farith3 (mcf::FMSUB) => (0ux3F, 0ux1C);
put_farith3 (mcf::FMSUBS) => (0ux3B, 0ux1C);
put_farith3 (mcf::FNMADD) => (0ux3F, 0ux1F);
put_farith3 (mcf::FNMADDS) => (0ux3B, 0ux1F);
put_farith3 (mcf::FNMSUB) => (0ux3F, 0ux1E);
put_farith3 (mcf::FNMSUBS) => (0ux3B, 0ux1E);
put_farith3 (mcf::FSEL) => (0ux3F, 0ux17);
end
also
fun put_bo (mcf::TRUE) => (0uxC : one_word_unt::Unt);
put_bo (mcf::FALSE) => (0ux4 : one_word_unt::Unt);
put_bo (mcf::ALWAYS) => (0ux14 : one_word_unt::Unt);
put_bo (mcf::COUNTER { eq_zero,
cond
}
) => case cond
#
NULL => if eq_zero 0ux12;
else 0ux10;
fi;
THE cc => case (eq_zero, cc)
#
(FALSE, FALSE) => 0ux0;
(FALSE, TRUE) => 0ux8;
(TRUE, FALSE) => 0ux2;
(TRUE, TRUE) => 0uxA;
esac;
esac;
end
also
fun put_arith (mcf::ADD) => (0ux10A : one_word_unt::Unt);
put_arith (mcf::SUBF) => (0ux28 : one_word_unt::Unt);
put_arith (mcf::MULLW) => (0uxEB : one_word_unt::Unt);
put_arith (mcf::MULLD) => (0uxE9 : one_word_unt::Unt);
put_arith (mcf::MULHW) => (0ux4B : one_word_unt::Unt);
put_arith (mcf::MULHWU) => (0uxB : one_word_unt::Unt);
put_arith (mcf::DIVW) => (0ux1EB : one_word_unt::Unt);
put_arith (mcf::DIVD) => (0ux1E9 : one_word_unt::Unt);
put_arith (mcf::DIVWU) => (0ux1CB : one_word_unt::Unt);
put_arith (mcf::DIVDU) => (0ux1C9 : one_word_unt::Unt);
put_arith (mcf::AND) => (0ux1C : one_word_unt::Unt);
put_arith (mcf::OR) => (0ux1BC : one_word_unt::Unt);
put_arith (mcf::XOR) => (0ux13C : one_word_unt::Unt);
put_arith (mcf::NAND) => (0ux1DC : one_word_unt::Unt);
put_arith (mcf::NOR) => (0ux7C : one_word_unt::Unt);
put_arith (mcf::EQV) => (0ux11C : one_word_unt::Unt);
put_arith (mcf::ANDC) => (0ux3C : one_word_unt::Unt);
put_arith (mcf::ORC) => (0ux19C : one_word_unt::Unt);
put_arith (mcf::SLW) => (0ux18 : one_word_unt::Unt);
put_arith (mcf::SLD) => (0ux1B : one_word_unt::Unt);
put_arith (mcf::SRW) => (0ux218 : one_word_unt::Unt);
put_arith (mcf::SRD) => (0ux21B : one_word_unt::Unt);
put_arith (mcf::SRAW) => (0ux318 : one_word_unt::Unt);
put_arith (mcf::SRAD) => (0ux31A : one_word_unt::Unt);
end
also
fun put_arithi (mcf::ADDI) => (0uxE : one_word_unt::Unt);
put_arithi (mcf::ADDIS) => (0uxF : one_word_unt::Unt);
put_arithi (mcf::SUBFIC) => (0ux8 : one_word_unt::Unt);
put_arithi (mcf::MULLI) => (0ux7 : one_word_unt::Unt);
put_arithi (mcf::ANDI_RC) => (0ux1C : one_word_unt::Unt);
put_arithi (mcf::ANDIS_RC) => (0ux1D : one_word_unt::Unt);
put_arithi (mcf::ORI) => (0ux18 : one_word_unt::Unt);
put_arithi (mcf::ORIS) => (0ux19 : one_word_unt::Unt);
put_arithi (mcf::XORI) => (0ux1A : one_word_unt::Unt);
put_arithi (mcf::XORIS) => (0ux1B : one_word_unt::Unt);
put_arithi (mcf::SRAWI) => error "SRAWI";
put_arithi (mcf::SRADI) => error "SRADI";
end
also
fun put_ccarith (mcf::CRAND) => (0ux101 : one_word_unt::Unt);
put_ccarith (mcf::CROR) => (0ux1C1 : one_word_unt::Unt);
put_ccarith (mcf::CRXOR) => (0uxC1 : one_word_unt::Unt);
put_ccarith (mcf::CRNAND) => (0uxE1 : one_word_unt::Unt);
put_ccarith (mcf::CRNOR) => (0ux21 : one_word_unt::Unt);
put_ccarith (mcf::CREQV) => (0ux121 : one_word_unt::Unt);
put_ccarith (mcf::CRANDC) => (0ux81 : one_word_unt::Unt);
put_ccarith (mcf::CRORC) => (0ux1A1 : one_word_unt::Unt);
end;
fun x_form { opcd,
rt,
ra,
rb,
xo,
rc
}
=
{ rc = put_bool rc;
e_word32 ((opcd << 0ux1A) + ((rt << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((xo << 0ux1) + rc)))));
}
also
fun xl_form { opcd,
bt,
ba,
bb,
xo,
lk
}
=
{ lk = put_bool lk;
e_word32 ((opcd << 0ux1A) + ((bt << 0ux15) + ((ba << 0ux10) + ((bb << 0uxB) + ((xo << 0ux1) + lk)))));
}
also
fun m_form { opcd,
rs,
ra,
rb,
mb,
me,
rc
}
=
{ rc = put_bool rc;
e_word32 ((opcd << 0ux1A) + ((rs << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((mb << 0ux6) + ((me << 0ux1) + rc))))));
}
also
fun a_form { opcd,
frt,
fra,
frb,
frc,
xo,
rc
}
=
{ rc = put_bool rc;
e_word32 ((opcd << 0ux1A) + ((frt << 0ux15) + ((fra << 0ux10) + ((frb << 0uxB) + ((frc << 0ux6) + ((xo << 0ux1) + rc))))));
}
also
fun loadx { rt,
ra,
rb,
xop
}
=
{ rt = put_int_register rt;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((rt << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((xop << 0ux1) + 0ux7C000000))));
}
also
fun loadd { opcd,
rt,
ra,
d
}
=
{ rt = put_int_register rt;
ra = put_int_register ra;
d = put_operand d;
e_word32 ((opcd << 0ux1A) + ((rt << 0ux15) + ((ra << 0ux10) + (d & 0uxFFFF))));
}
also
fun loadde { opcd,
rt,
ra,
de,
xop
}
=
{ rt = put_int_register rt;
ra = put_int_register ra;
de = put_operand de;
e_word32 ((opcd << 0ux1A) + ((rt << 0ux15) + ((ra << 0ux10) + (((de & 0uxFFF) << 0ux4) + xop))));
}
also
fun load { ld,
rt,
ra,
d
}
=
case (d, ld)
#
(mcf::REG_OP rb, mcf::LBZ) => loadx { rt,
ra,
rb,
xop => 0ux57
}
;
(mcf::REG_OP rb, mcf::LBZE) => loadx { rt,
ra,
rb,
xop => 0ux5F
}
;
(mcf::REG_OP rb, mcf::LHZ) => loadx { rt,
ra,
rb,
xop => 0ux117
}
;
(mcf::REG_OP rb, mcf::LHZE) => loadx { rt,
ra,
rb,
xop => 0ux11F
}
;
(mcf::REG_OP rb, mcf::LHA) => loadx { rt,
ra,
rb,
xop => 0ux157
}
;
(mcf::REG_OP rb, mcf::LHAE) => loadx { rt,
ra,
rb,
xop => 0ux15F
}
;
(mcf::REG_OP rb, mcf::LWZ) => loadx { rt,
ra,
rb,
xop => 0ux17
}
;
(mcf::REG_OP rb, mcf::LWZE) => loadx { rt,
ra,
rb,
xop => 0ux1F
}
;
(mcf::REG_OP rb, mcf::LDE) => loadx { rt,
ra,
rb,
xop => 0ux31F
}
;
(d, mcf::LBZ) => loadd { opcd => 0ux22,
rt,
ra,
d
}
;
(de, mcf::LBZE) => loadde { opcd => 0ux3A,
rt,
ra,
de,
xop => 0ux0
}
;
(d, mcf::LHZ) => loadd { opcd => 0ux28,
rt,
ra,
d
}
;
(de, mcf::LHZE) => loadde { opcd => 0ux3A,
rt,
ra,
de,
xop => 0ux2
}
;
(d, mcf::LHA) => loadd { opcd => 0ux2A,
rt,
ra,
d
}
;
(de, mcf::LHAE) => loadde { opcd => 0ux3A,
rt,
ra,
de,
xop => 0ux4
}
;
(d, mcf::LWZ) => loadd { opcd => 0ux20,
rt,
ra,
d
}
;
(de, mcf::LWZE) => loadde { opcd => 0ux3A,
rt,
ra,
de,
xop => 0ux6
}
;
(de, mcf::LDE) => loadde { opcd => 0ux3E,
rt,
ra,
de,
xop => 0ux0
}
;
(mcf::REG_OP rb, mcf::LHAU) => loadx { rt,
ra,
rb,
xop => 0ux177
}
;
(mcf::REG_OP rb, mcf::LHZU) => loadx { rt,
ra,
rb,
xop => 0ux137
}
;
(mcf::REG_OP rb, mcf::LWZU) => loadx { rt,
ra,
rb,
xop => 0ux37
}
;
(d, mcf::LHZU) => loadd { opcd => 0ux29,
rt,
ra,
d
}
;
(d, mcf::LWZU) => loadd { opcd => 0ux21,
rt,
ra,
d
}
;
_ => error "load";
esac
also
fun floadx { ft,
ra,
rb,
xop
}
=
{ ft = put_float_register ft;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((ft << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((xop << 0ux1) + 0ux7C000000))));
}
also
fun floadd { opcd,
ft,
ra,
d
}
=
{ ft = put_float_register ft;
ra = put_int_register ra;
d = put_operand d;
e_word32 ((opcd << 0ux1A) + ((ft << 0ux15) + ((ra << 0ux10) + (d & 0uxFFFF))));
}
also
fun floadde { opcd,
ft,
ra,
de,
xop
}
=
{ ft = put_float_register ft;
ra = put_int_register ra;
de = put_operand de;
e_word32 ((opcd << 0ux1A) + ((ft << 0ux15) + ((ra << 0ux10) + (((de & 0uxFFF) << 0ux4) + xop))));
}
also
fun fload { ld,
ft,
ra,
d
}
=
case (d, ld)
#
(mcf::REG_OP rb, mcf::LFS) => floadx { ft,
ra,
rb,
xop => 0ux217
}
;
(mcf::REG_OP rb, mcf::LFSE) => floadx { ft,
ra,
rb,
xop => 0ux21F
}
;
(mcf::REG_OP rb, mcf::LFD) => floadx { ft,
ra,
rb,
xop => 0ux257
}
;
(mcf::REG_OP rb, mcf::LFDE) => floadx { ft,
ra,
rb,
xop => 0ux25F
}
;
(mcf::REG_OP rb, mcf::LFDU) => floadx { ft,
ra,
rb,
xop => 0ux277
}
;
(d, mcf::LFS) => floadd { ft,
ra,
d,
opcd => 0ux30
}
;
(de, mcf::LFSE) => floadde { ft,
ra,
de,
opcd => 0ux3E,
xop => 0ux4
}
;
(d, mcf::LFD) => floadd { ft,
ra,
d,
opcd => 0ux32
}
;
(de, mcf::LFDE) => floadde { ft,
ra,
de,
opcd => 0ux3E,
xop => 0ux6
}
;
(d, mcf::LFDU) => floadd { ft,
ra,
d,
opcd => 0ux33
}
;
_ => error "fload";
esac
also
fun storex { rs,
ra,
rb,
xop
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((xop << 0ux1) + 0ux7C000000))));
}
also
fun stored { opcd,
rs,
ra,
d
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
d = put_operand d;
e_word32 ((opcd << 0ux1A) + ((rs << 0ux15) + ((ra << 0ux10) + (d & 0uxFFFF))));
}
also
fun storede { opcd,
rs,
ra,
de,
xop
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
de = put_operand de;
e_word32 ((opcd << 0ux1A) + ((rs << 0ux15) + ((ra << 0ux10) + (((de & 0uxFFF) << 0ux4) + xop))));
}
also
fun store { st,
rs,
ra,
d
}
=
case (d, st)
#
(mcf::REG_OP rb, mcf::STB) => storex { rs,
ra,
rb,
xop => 0uxD7
}
;
(mcf::REG_OP rb, mcf::STBE) => storex { rs,
ra,
rb,
xop => 0uxDF
}
;
(mcf::REG_OP rb, mcf::STH) => storex { rs,
ra,
rb,
xop => 0ux197
}
;
(mcf::REG_OP rb, mcf::STHE) => storex { rs,
ra,
rb,
xop => 0ux19F
}
;
(mcf::REG_OP rb, mcf::STW) => storex { rs,
ra,
rb,
xop => 0ux97
}
;
(mcf::REG_OP rb, mcf::STWE) => storex { rs,
ra,
rb,
xop => 0ux9F
}
;
(mcf::REG_OP rb, mcf::STDE) => storex { rs,
ra,
rb,
xop => 0ux39F
}
;
(d, mcf::STB) => stored { rs,
ra,
d,
opcd => 0ux26
}
;
(de, mcf::STBE) => storede { rs,
ra,
de,
opcd => 0ux3A,
xop => 0ux8
}
;
(d, mcf::STH) => stored { rs,
ra,
d,
opcd => 0ux2C
}
;
(de, mcf::STHE) => storede { rs,
ra,
de,
opcd => 0ux3A,
xop => 0uxA
}
;
(d, mcf::STW) => stored { rs,
ra,
d,
opcd => 0ux24
}
;
(de, mcf::STWE) => storede { rs,
ra,
de,
opcd => 0ux3A,
xop => 0uxE
}
;
(de, mcf::STDE) => storede { rs,
ra,
de,
opcd => 0ux3E,
xop => 0ux8
}
;
_ => error "store";
esac
also
fun fstorex { fs,
ra,
rb,
xop
}
=
{ fs = put_float_register fs;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((fs << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((xop << 0ux1) + 0ux7C000000))));
}
also
fun fstored { opcd,
fs,
ra,
d
}
=
{ fs = put_float_register fs;
ra = put_int_register ra;
d = put_operand d;
e_word32 ((opcd << 0ux1A) + ((fs << 0ux15) + ((ra << 0ux10) + (d & 0uxFFFF))));
}
also
fun fstorede { opcd,
fs,
ra,
de,
xop
}
=
{ fs = put_float_register fs;
ra = put_int_register ra;
de = put_operand de;
e_word32 ((opcd << 0ux1A) + ((fs << 0ux15) + ((ra << 0ux10) + (((de & 0uxFFF) << 0ux4) + xop))));
}
also
fun fstore { st,
fs,
ra,
d
}
=
case (d, st)
#
(mcf::REG_OP rb, mcf::STFS) => fstorex { fs,
ra,
rb,
xop => 0ux297
}
;
(mcf::REG_OP rb, mcf::STFSE) => fstorex { fs,
ra,
rb,
xop => 0ux29F
}
;
(mcf::REG_OP rb, mcf::STFD) => fstorex { fs,
ra,
rb,
xop => 0ux2D7
}
;
(mcf::REG_OP rb, mcf::STFDE) => fstorex { fs,
ra,
rb,
xop => 0ux2F7
}
;
(d, mcf::STFS) => fstored { fs,
ra,
d,
opcd => 0ux34
}
;
(de, mcf::STFSE) => fstorede { fs,
ra,
de,
opcd => 0ux3E,
xop => 0uxC
}
;
(d, mcf::STFD) => fstored { fs,
ra,
d,
opcd => 0ux36
}
;
(de, mcf::STFDE) => fstorede { fs,
ra,
de,
opcd => 0ux3E,
xop => 0uxE
}
;
_ => error "fstore";
esac
also
fun unary' { ra,
rt,
oe,
oper,
rc
}
=
{ ra = put_int_register ra;
rt = put_int_register rt;
oe = put_bool oe;
oper = put_unary oper;
rc = put_bool rc;
e_word32 ((ra << 0ux15) + ((rt << 0ux10) + ((oe << 0uxA) + ((oper << 0ux1) + (rc + 0ux7C000000)))));
}
also
fun unary { ra,
rt,
oper,
oe,
rc
}
=
case oper
#
mcf::NEG => unary' { ra => rt,
rt => ra,
oper,
oe,
rc
}
;
_ => unary' { ra,
rt,
oper,
oe,
rc
}
;
esac
also
fun arith' { rt,
ra,
rb,
oe,
oper,
rc
}
=
{ rt = put_int_register rt;
ra = put_int_register ra;
rb = put_int_register rb;
oe = put_bool oe;
oper = put_arith oper;
rc = put_bool rc;
e_word32 ((rt << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + ((oe << 0uxA) + ((oper << 0ux1) + (rc + 0ux7C000000))))));
}
also
fun arithi' { oper,
rt,
ra,
im
}
=
{ oper = put_arithi oper;
rt = put_int_register rt;
ra = put_int_register ra;
im = put_operand im;
e_word32 ((oper << 0ux1A) + ((rt << 0ux15) + ((ra << 0ux10) + (im & 0uxFFFF))));
}
also
fun srawi { rs,
ra,
sh
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
sh = put_operand sh;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + (((sh & 0ux1F) << 0uxB) + 0ux7C000670)));
}
also
fun sradi' { rs,
ra,
sh,
sh2
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((sh2 << 0ux1) + 0ux7C000674))));
}
also
fun sradi { rs,
ra,
sh
}
=
{ sh = put_operand sh;
sradi' { rs,
ra,
sh => (sh & 0ux1F),
sh2 => ((sh << 0ux5) & 0ux1)
}
;
}
also
fun arith { oper,
rt,
ra,
rb,
oe,
rc
}
=
case oper
#
(mcf::ADD
| mcf::SUBF | mcf::MULLW | mcf::MULLD | mcf::MULHW | mcf::MULHWU | mcf::DIVW | mcf::DIVD | mcf::DIVWU | mcf::DIVDU) => arith' { oper,
rt,
ra,
rb,
oe,
rc
}
;
_ => arith' { oper,
rt => ra,
ra => rt,
rb,
oe,
rc
}
;
esac
also
fun arithi { oper,
rt,
ra,
im
}
=
case oper
#
(mcf::ADDI
| mcf::ADDIS | mcf::SUBFIC | mcf::MULLI) => arithi' { oper,
rt,
ra,
im
}
;
mcf::SRAWI => srawi { rs => ra,
ra => rt,
sh => im
}
;
mcf::SRADI => sradi { rs => ra,
ra => rt,
sh => im
}
;
_ => arithi' { oper,
rt => ra,
ra => rt,
im
}
;
esac
also
fun cmpl { bf,
l,
ra,
rb
}
=
{ bf = put_flags_register bf;
l = put_bool l;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((bf << 0ux17) + ((l << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C000040))));
}
also
fun cmpli { bf,
l,
ra,
ui
}
=
{ bf = put_flags_register bf;
l = put_bool l;
ra = put_int_register ra;
ui = put_operand ui;
e_word32 ((bf << 0ux17) + ((l << 0ux15) + ((ra << 0ux10) + ((ui & 0uxFFFF) + 0ux28000000))));
}
also
fun cmp { bf,
l,
ra,
rb
}
=
{ bf = put_flags_register bf;
l = put_bool l;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((bf << 0ux17) + ((l << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C000000))));
}
also
fun cmpi { bf,
l,
ra,
si
}
=
{ bf = put_flags_register bf;
l = put_bool l;
ra = put_int_register ra;
si = put_operand si;
e_word32 ((bf << 0ux17) + ((l << 0ux15) + ((ra << 0ux10) + ((si & 0uxFFFF) + 0ux2C000000))));
}
also
fun compare { cmp',
bf,
l,
ra,
rb
}
=
case (cmp', rb)
#
(mcf::CMP, mcf::REG_OP rb) => cmp { bf,
l,
ra,
rb
}
;
(mcf::CMPL, mcf::REG_OP rb) => cmpl { bf,
l,
ra,
rb
}
;
(mcf::CMP, si) => cmpi { bf,
l,
ra,
si
}
;
(mcf::CMPL, ui) => cmpli { bf,
l,
ra,
ui
}
;
esac
also
fun fcmp { bf,
fa,
fb,
cmp
}
=
{ bf = put_flags_register bf;
fa = put_float_register fa;
fb = put_float_register fb;
cmp = put_fcmp cmp;
e_word32 ((bf << 0ux17) + ((fa << 0ux10) + ((fb << 0uxB) + ((cmp << 0ux1) + 0uxFC000000))));
}
also
fun funary { oper,
ft,
fb,
rc
}
=
{ oper = put_funary oper;
ft = put_float_register ft;
fb = put_float_register fb;
{
###line 482.12 "src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description"
my (opcd, xo) = oper;
case oper
#
(0ux3F, 0ux16) => a_form { opcd,
frt => ft,
fra => 0ux0,
frb => fb,
frc => 0ux0,
xo,
rc
}
;
(0ux3B, 0ux16) => a_form { opcd,
frt => ft,
fra => 0ux0,
frb => fb,
frc => 0ux0,
xo,
rc
}
;
_ => x_form { opcd,
rt => ft,
ra => 0ux0,
rb => fb,
xo,
rc
}
;
esac;
};
}
also
fun farith { oper,
ft,
fa,
fb,
rc
}
=
{ ft = put_float_register ft;
fa = put_float_register fa;
fb = put_float_register fb;
{
###line 495.12 "src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description"
my (opcd, xo) = put_farith oper;
case oper
#
(mcf::FMUL
| mcf::FMULS) => a_form { opcd,
frt => ft,
fra => fa,
frb => 0ux0,
frc => fb,
xo,
rc
}
;
_ => a_form { opcd,
frt => ft,
fra => fa,
frb => fb,
frc => 0ux0,
xo,
rc
}
;
esac;
};
}
also
fun farith3 { oper,
ft,
fa,
fc,
fb,
rc
}
=
{ oper = put_farith3 oper;
ft = put_float_register ft;
fa = put_float_register fa;
fc = put_float_register fc;
fb = put_float_register fb;
{
###line 504.12 "src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description"
my (opcd, xo) = oper;
a_form { opcd,
frt => ft,
fra => fa,
frb => fb,
frc => fc,
xo,
rc
}
;
};
}
also
fun cr_bit { cc }
=
{
###line 509.12 "src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description"
my (cr, bit) = cc;
((put_flags_register cr) << 0ux2) + (u32::from_int case bit
#
mcf::LT => 0;
mcf::GT => 1;
mcf::EQ => 2;
mcf::SO => 3;
mcf::FL => 0;
mcf::FG => 1;
mcf::FE => 2;
mcf::FU => 3;
mcf::FX => 0;
mcf::FEX => 1;
mcf::VX => 2;
mcf::OX => 3;
esac);
}
also
fun ccarith { oper,
bt,
ba,
bb
}
=
{ oper = put_ccarith oper;
xl_form { opcd => 0ux13,
bt => cr_bit { cc => bt },
ba => cr_bit { cc => ba },
bb => cr_bit { cc => bb },
xo => oper,
lk => FALSE
}
;
}
also
fun twr { to,
ra,
rb
}
=
{ to = put_int to;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((to << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C000008)));
}
also
fun twi { to,
ra,
si
}
=
{ to = put_int to;
ra = put_int_register ra;
si = put_operand si;
e_word32 ((to << 0ux15) + ((ra << 0ux10) + ((si & 0uxFFFF) + 0uxC000000)));
}
also
fun tw { to,
ra,
si
}
=
case si
#
mcf::REG_OP rb => twr { to,
ra,
rb
}
;
_ => twi { to,
ra,
si
}
;
esac
also
fun tdr { to,
ra,
rb
}
=
{ to = put_int to;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((to << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C000088)));
}
also
fun tdi { to,
ra,
si
}
=
{ to = put_int to;
ra = put_int_register ra;
si = put_operand si;
e_word32 ((to << 0ux15) + ((ra << 0ux10) + ((si & 0uxFFFF) + 0ux8000000)));
}
also
fun td { to,
ra,
si
}
=
case si
#
mcf::REG_OP rb => tdr { to,
ra,
rb
}
;
_ => tdi { to,
ra,
si
}
;
esac
also
fun mcrf { bf,
bfa
}
=
{ bf = put_flags_register bf;
bfa = put_flags_register bfa;
e_word32 ((bf << 0ux17) + ((bfa << 0ux12) + 0ux4C000000));
}
also
fun mtspr' { rs,
spr
}
=
{ rs = put_int_register rs;
e_word32 ((rs << 0ux15) + ((spr << 0uxB) + 0ux7C0003A6));
}
also
fun mtspr { rs,
spr
}
=
{ spr = put_spr spr;
mtspr' { rs,
spr => ((spr & 0ux1F) << 0ux5) + ((spr << 0ux5) & 0ux1F)
}
;
}
also
fun mfspr' { rt,
spr
}
=
{ rt = put_int_register rt;
e_word32 ((rt << 0ux15) + ((spr << 0uxB) + 0ux7C0002A6));
}
also
fun mfspr { rt,
spr
}
=
{ spr = put_spr spr;
mfspr' { rt,
spr => ((spr & 0ux1F) << 0ux5) + ((spr << 0ux5) & 0ux1F)
}
;
}
also
fun b { li,
aa,
lk
}
=
{ aa = put_bool aa;
lk = put_bool lk;
e_word32 (((li & 0uxFFFFFF) << 0ux2) + ((aa << 0ux1) + (lk + 0ux48000000)));
}
also
fun be { li,
aa,
lk
}
=
{ aa = put_bool aa;
lk = put_bool lk;
e_word32 (((li & 0uxFFFFFF) << 0ux2) + ((aa << 0ux1) + (lk + 0ux58000000)));
}
also
fun bc { bo,
bi,
bd,
aa,
lk
}
=
{ bo = put_bo bo;
aa = put_bool aa;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (((bd & 0ux3FFF) << 0ux2) + ((aa << 0ux1) + (lk + 0ux40000000)))));
}
also
fun bce { bo,
bi,
bd,
aa,
lk
}
=
{ bo = put_bo bo;
aa = put_bool aa;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (((bd & 0ux3FFF) << 0ux2) + ((aa << 0ux1) + (lk + 0ux40000000)))));
}
also
fun bclr { bo,
bi,
lk
}
=
{ bo = put_bo bo;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (lk + 0ux4C000020)));
}
also
fun bclre { bo,
bi,
lk
}
=
{ bo = put_bo bo;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (lk + 0ux4C000022)));
}
also
fun bcctr { bo,
bi,
lk
}
=
{ bo = put_bo bo;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (lk + 0ux4C000420)));
}
also
fun bcctre { bo,
bi,
lk
}
=
{ bo = put_bo bo;
lk = put_bool lk;
e_word32 ((bo << 0ux15) + ((bi << 0ux10) + (lk + 0ux4C000422)));
}
also
fun rlwnm { rs,
ra,
sh,
mb,
me
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
sh = put_int_register sh;
mb = put_int mb;
me = put_int me;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((me << 0ux1) + 0ux5C000000)))));
}
also
fun rlwinm { rs,
ra,
sh,
mb,
me
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
me = put_int me;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((me << 0ux1) + 0ux54000000)))));
}
also
fun rldcl { rs,
ra,
sh,
mb
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
sh = put_int_register sh;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + 0ux78000010))));
}
also
fun rldicl { rs,
ra,
sh,
mb,
sh2
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((sh2 << 0ux1) + 0ux78000000)))));
}
also
fun rldcr { rs,
ra,
sh,
mb
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
sh = put_int_register sh;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + 0ux78000012))));
}
also
fun rldicr { rs,
ra,
sh,
mb,
sh2
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((sh2 << 0ux1) + 0ux78000004)))));
}
also
fun rldic { rs,
ra,
sh,
mb,
sh2
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((sh2 << 0ux1) + 0ux78000008)))));
}
also
fun rlwimi { rs,
ra,
sh,
mb,
me
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
me = put_int me;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((me << 0ux1) + 0ux50000000)))));
}
also
fun rldimi { rs,
ra,
sh,
mb,
sh2
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
mb = put_int mb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((sh << 0uxB) + ((mb << 0ux6) + ((sh2 << 0ux1) + 0ux7800000C)))));
}
also
fun rotate { oper,
ra,
rs,
sh,
mb,
me
}
=
case (oper, me)
#
(mcf::RLWNM, THE me) => rlwnm { ra,
rs,
sh,
mb,
me
}
;
(mcf::RLDCL, _) => rldcl { ra,
rs,
sh,
mb
}
;
(mcf::RLDCR, _) => rldcr { ra,
rs,
sh,
mb
}
;
_ => error "rotate";
esac
also
fun rotatei { oper,
ra,
rs,
sh,
mb,
me
}
=
{ sh = put_operand sh;
case (oper, me)
#
(mcf::RLWINM, THE me) => rlwinm { ra,
rs,
sh,
mb,
me
}
;
(mcf::RLWIMI, THE me) => rlwimi { ra,
rs,
sh,
mb,
me
}
;
(mcf::RLDICL, _) => rldicl { ra,
rs,
sh => (sh & 0ux1F),
sh2 => ((sh << 0ux5) & 0ux1),
mb
}
;
(mcf::RLDICR, _) => rldicr { ra,
rs,
sh => (sh & 0ux1F),
sh2 => ((sh << 0ux5) & 0ux1),
mb
}
;
(mcf::RLDIC, _) => rldic { ra,
rs,
sh => (sh & 0ux1F),
sh2 => ((sh << 0ux5) & 0ux1),
mb
}
;
(mcf::RLDIMI, _) => rldimi { ra,
rs,
sh => (sh & 0ux1F),
sh2 => ((sh << 0ux5) & 0ux1),
mb
}
;
_ => error "rotatei";
esac;
}
also
fun lwarx { rt,
ra,
rb
}
=
{ rt = put_int_register rt;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((rt << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C000028)));
}
also
fun stwcx { rs,
ra,
rb
}
=
{ rs = put_int_register rs;
ra = put_int_register ra;
rb = put_int_register rb;
e_word32 ((rs << 0ux15) + ((ra << 0ux10) + ((rb << 0uxB) + 0ux7C00012D)));
};
###line 605.7 "src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description"
fun relative (mcf::LABEL_OP label_expression) => (u32::from_int ((tce::value_of label_expression) - (deref loc))) >>> 0ux2;
relative _ => error "relative";
end;
fun emitter instruction
=
{
fun put_op (mcf::LL { ld,
rt,
ra,
d,
ramregion
}
) => load { ld,
rt,
ra,
d
}
;
put_op (mcf::LF { ld,
ft,
ra,
d,
ramregion
}
) => fload { ld,
ft,
ra,
d
}
;
put_op (mcf::ST { st,
rs,
ra,
d,
ramregion
}
) => store { st,
rs,
ra,
d
}
;
put_op (mcf::STF { st,
fs,
ra,
d,
ramregion
}
) => fstore { st,
fs,
ra,
d
}
;
put_op (mcf::UNARY { oper,
rt,
ra,
rc,
oe
}
) => unary { oper,
rt,
ra,
oe,
rc
}
;
put_op (mcf::ARITH { oper,
rt,
ra,
rb,
rc,
oe
}
) => arith { oper,
rt,
ra,
rb,
oe,
rc
}
;
put_op (mcf::ARITHI { oper,
rt,
ra,
im
}
) => arithi { oper,
rt,
ra,
im
}
;
put_op (mcf::ROTATE { oper,
ra,
rs,
sh,
mb,
me
}
) => rotate { oper,
ra,
rs,
sh,
mb,
me
}
;
put_op (mcf::ROTATEI { oper,
ra,
rs,
sh,
mb,
me
}
) => rotatei { oper,
ra,
rs,
sh,
mb,
me
}
;
put_op (mcf::COMPARE { cmp,
l,
bf,
ra,
rb
}
) => compare { cmp' => cmp,
bf,
l,
ra,
rb
}
;
put_op (mcf::FCOMPARE { cmp,
bf,
fa,
fb
}
) => fcmp { cmp,
bf,
fa,
fb
}
;
put_op (mcf::FUNARY { oper,
ft,
fb,
rc
}
) => funary { oper,
ft,
fb,
rc
}
;
put_op (mcf::FARITH { oper,
ft,
fa,
fb,
rc
}
) => farith { oper,
ft,
fa,
fb,
rc
}
;
put_op (mcf::FARITH3 { oper,
ft,
fa,
fb,
fc,
rc
}
) => farith3 { oper,
ft,
fa,
fb,
fc,
rc
}
;
put_op (mcf::CCARITH { oper,
bt,
ba,
bb
}
) => ccarith { oper,
bt,
ba,
bb
}
;
put_op (mcf::MCRF { bf,
bfa
}
) => mcrf { bf,
bfa
}
;
put_op (mcf::MTSPR { rs,
spr
}
) => mtspr { rs,
spr
}
;
put_op (mcf::MFSPR { rt,
spr
}
) => mfspr { rt,
spr
}
;
put_op (mcf::LWARX { rt,
ra,
rb
}
) => lwarx { rt,
ra,
rb
}
;
put_op (mcf::STWCX { rs,
ra,
rb
}
) => stwcx { rs,
ra,
rb
}
;
put_op (mcf::TW { to,
ra,
si
}
) => tw { to,
ra,
si
}
;
put_op (mcf::TD { to,
ra,
si
}
) => td { to,
ra,
si
}
;
put_op (mcf::BC { bo,
bf,
bit,
address,
lk,
fall
}
) => bc { bo,
bi => cr_bit { cc => (bf, bit) },
bd => relative address,
aa => FALSE,
lk => lk
}
;
put_op (mcf::BCLR { bo,
bf,
bit,
lk,
labels
}
) => bclr { bo,
bi => cr_bit { cc => (bf, bit) },
lk => lk
}
;
put_op (mcf::BB { address,
lk
}
) => b { li => relative address,
aa => FALSE,
lk => lk
}
;
put_op (mcf::CALL { def,
uses,
cuts_to,
ramregion
}
) => bclr { bo => mcf::ALWAYS,
bi => 0ux0,
lk => TRUE
}
;
put_op (mcf::SOURCE { }) => ();
put_op (mcf::SINK { }) => ();
put_op (mcf::PHI { }) => ();
end;
put_op instruction;
};
fun put_op (mcf::NOTE { op, ... } ) => put_op op;
put_op (mcf::BASE_OP i) => emitter i;
put_op (mcf::LIVE _) => ();
put_op (mcf::DEAD _) => ();
put_op _ => error "put_op";
end;
{ start_new_cccomponent,
put_pseudo_op,
put_op,
get_completed_cccomponent=>fail,
put_private_label=>do_nothing,
put_public_label=>do_nothing,
put_comment=>do_nothing,
put_fn_liveout_info=>do_nothing,
put_bblock_note=>do_nothing,
get_notes
};
};
};
end;