1 { 2 Copyright (c) 1998-2010 by Florian Klaempfl and Jonas Maebe 3 Member of the Free Pascal development team 4 5 This unit contains high-level code generator support for ppc32 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 21 **************************************************************************** 22 } 23 24 unit hlcgcpu; 25 26 {$i fpcdefs.inc} 27 28 interface 29 30 uses 31 aasmdata, 32 symtype, 33 cgbase,cgutils,hlcgobj,hlcgppc; 34 35 type 36 thlcgcpu = class(thlcgppcgen) 37 procedure a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister); override; 38 procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tdef; const fromsreg, tosreg: tsubsetregister); override; 39 protected 40 procedure a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); override; 41 end; 42 43 procedure create_hlcodegen; 44 45 implementation 46 47 uses 48 verbose, 49 cpubase,aasmcpu, 50 defutil, 51 cgobj,cgcpu; 52 53 { thlcgppc } 54 55 procedure thlcgcpu.a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister); 56 var 57 cgsubsetsize, 58 cgtosize: tcgsize; 59 begin 60 if (sreg.bitlen > 32) then 61 internalerror(2008020701); 62 cgsubsetsize:=def_cgsize(subsetsize); 63 cgtosize:=def_cgsize(tosize); 64 if (sreg.bitlen <> 32) then 65 begin 66 list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg, 67 sreg.subsetreg,(32-sreg.startbit) and 31,32-sreg.bitlen,31)); 68 { types with a negative lower bound are always a base type (8, 16, 32 bits) } 69 if (cgsubsetsize in [OS_S8..OS_S128]) then 70 if ((sreg.bitlen mod 8) = 0) then 71 begin 72 cg.a_load_reg_reg(list,tcgsize2unsigned[cgsubsetsize],cgsubsetsize,destreg,destreg); 73 cg.a_load_reg_reg(list,cgsubsetsize,cgtosize,destreg,destreg); 74 end 75 else 76 begin 77 cg.a_op_const_reg(list,OP_SHL,OS_INT,32-sreg.bitlen,destreg); 78 cg.a_op_const_reg(list,OP_SAR,OS_INT,32-sreg.bitlen,destreg); 79 end; 80 end 81 else 82 cg.a_load_reg_reg(list,cgsubsetsize,cgtosize,sreg.subsetreg,destreg); 83 end; 84 85 86 procedure thlcgcpu.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tdef; const fromsreg, tosreg: tsubsetregister); 87 begin 88 if (tosreg.bitlen>32) or (tosreg.startbit>31) then 89 internalerror(2008020703); 90 if (fromsreg.bitlen>=tosreg.bitlen) then 91 list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosreg.subsetreg, fromsreg.subsetreg, 92 (tosreg.startbit-fromsreg.startbit) and 31, 93 32-tosreg.startbit-tosreg.bitlen,31-tosreg.startbit)) 94 else 95 inherited a_load_subsetreg_subsetreg(list,fromsubsetsize,tosubsetsize,fromsreg,tosreg); 96 end; 97 98 99 procedure thlcgcpu.a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); 100 begin 101 if (slopt in [SL_SETZERO,SL_SETMAX]) then 102 inherited a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,sreg,slopt) 103 else if (sreg.bitlen>32) then 104 internalerror(2008020702) 105 else if (sreg.bitlen<>32) then 106 list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,sreg.subsetreg,fromreg, 107 sreg.startbit,32-sreg.startbit-sreg.bitlen,31-sreg.startbit)) 108 else 109 cg.a_load_reg_reg(list,def_cgsize(fromsize),def_cgsize(subsetsize),fromreg,sreg.subsetreg); 110 end; 111 112 113 114 procedure create_hlcodegen; 115 begin 116 hlcg:=thlcgcpu.create; 117 create_codegen; 118 end; 119 120 121 begin 122 chlcgobj:=thlcgcpu; 123 end. 124 125