PreviousUpNext

15.4.342  src/lib/compiler/back/low/pwrpc32/emit/translate-machcode-to-execode-pwrpc32-g.codemade.pkg

## 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.pkg
herein

    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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext