Quellcode durchsuchen

+ initial implementation for PowerPC based on the Alpha stuff

Jonas Maebe vor 26 Jahren
Ursprung
Commit
89b7d18f54

+ 623 - 0
compiler/new/powerpc/agas.pas

@@ -0,0 +1,623 @@
+{
+    $Id$
+    Copyright (c) 1997 by Florian Klaempfl
+
+    This unit implements an asm for the PowerPC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit agas;
+
+  interface
+
+    uses
+       dos,globals,systems,errors,cobjects,aasm,alpha,strings,files
+{$ifdef GDB}
+       ,gdb
+{$endif GDB}
+       ;
+
+    type
+      palphaattasmlist=^talphaattasmlist;
+      talphaattasmlist=object(tasmlist)
+        procedure WriteTree(p:paasmoutput);virtual;
+        procedure WriteAsmList;virtual;
+{$ifdef GDB}
+        procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
+{$endif}
+      end;
+
+  implementation
+
+    const
+       op2str : array[tasmop] of string[14] = ('<none>',
+    'add','add_','addo','addo_','addc','addc_','addco','addco_,
+    'adde','adde_','addeo','addeo_','addi','addic','addic_','addis,
+    'addme','addme_','addmeo','addmeo_','addze','addze_','addzeo,
+    'addzeo_','and','and_','andc','andc_','andi_','andis_','b,
+    'ba','bl','bla','bc','bca','bcl','bcla','bcctr','bcctrl','bclr,
+    'bclrl','cmp','cmpi','cmpl','cmpli','cntlzw','cntlzw_','crand,
+    'crandc','creqv','crnand','crnor','cror','crorc','crxor','dcba,
+    'dcbf','dcbi','dcbst','dcbt','divw','divw_','divwo','divwo_,
+    'divwu','divwu_','divwuo','divwuo_','eciwx','ecowx','eieio','eqv,
+    'eqv_','extsb','extsb_','extsh','extsh_','fabs','fabs_','fadd,
+    'fadd_','fadds','fadds_','fcompo','fcmpu','fctiw','fctw_','fctwz,
+    'fctwz_','fdiv','fdiv_','fdivs','fdivs_','fmadd','fmadd_','fmadds,
+    'fmadds_','fmr','fmsub','fmsub_','fmsubs','fmsubs_','fmul','fmul_,
+    'fmuls','fmuls_','fnabs','fnabs_','fneg','fneg_','fnmadd,
+    'fnmadd_','fnmadds','fnmadds_','fnmsub','fnmsub_','fnmsubs,
+    'fnmsubs_','fres','fres_','frsp','frsp_','frsqrte','frsqrte_,
+    'fsel','fsel_','fsqrt','fsqrt_','fsqrts','fsqrts_','fsub','fsub_,
+    'fsubs','fsubs_','icbi','isync','lbz','lbzu','lbzux','lbzx,
+    'lfd','lfdu','lfdux','lfdx','lfs','lfsu','lfsux','lfsx','lha,
+    'lhau','lhaux','lhax','hbrx','lhz','lhzu','lhzux','lhzx','lmw,
+    'lswi','lswx','lwarx','lwbrx','lwz','lwzu','lwzux','lwzx','mcrf,
+    'mcrfs','lcrxe','mfcr','mffs','maffs_','mfmsr','mfspr','mfsr,
+    'mfsrin','mftb','mtfcrf','mtfd0','mtfsb1','mtfsf','mtfsf_,
+    'mtfsfi','mtfsfi_','mtmsr','mtspr','mtsr','mtsrin','mulhw,
+    'mulhw_','mulhwu','mulhwu_','mulli','mullh','mullw_','mullwo,
+    'mullwo_','nand','nand_','neg','neg_','nego','nego_','nor','nor_,
+    'or','or_','orc','orc_','ori','oris', 'rfi', 'rlwimi', 'rlwimi_',
+    'rlwinm', 'tlwinm_','rlwnm','sc','slw', 'slw_', 'sraw', 'sraw_,
+    'srawi', 'srawi_','srw', 'srw_', 'stb', 'stbu', 'stbux','stbx','stfd',
+    'stfdu', 'stfdux', 'stfdx', 'stfiwx', 'stfs', 'stfsu', 'stfsux', 'stfsx',
+    'sth', 'sthbrx', 'sthu', 'sthux', 'sthx', 'stmw', 'stswi', 'stswx', 'stw',
+    'stwbrx', 'stwx_', 'stwu', 'stwux', 'stwx', 'subf', 'subf_', 'subfo',
+    'subfo_', 'subfc', 'subc_', 'subfco', 'subfco_', 'subfe', 'subfe_',
+    'subfeo', 'subfeo_', 'subfic', 'subfme', 'subfme_', 'subfmeo', 'subfmeo_,
+    'subfze', 'subfze_', 'subfzeo', 'subfzeo_', 'sync', 'tlbia', 'tlbie,
+    'tlbsync', 'tw', 'twi', 'xor', 'xor_', 'xori', 'xoris',
+    { some simplified mnemonics }
+    'subi', 'subis', 'subic', 'subic_', 'sub', 'sub_', 'subo', 'subo_',
+    'subc', 'subc_', 'subco', '_subco_', 'cmpwi', 'cmpw', 'cmplwi', 'cmplw',
+    'extlwi', 'extlwi_', 'extrwi', 'extrwi_', 'inslwi', 'inslwi_', 'insrwi',
+    'insrwi_', 'rotlwi', 'rotlwi_', 'rotlw', 'rotlw_', 'slwi', 'slwi_',
+    'srwi', 'srwi_', 'clrlwi', 'clrlwi_', 'clrrwi', 'clrrwi_', 'clrslwi',
+    'clrslwi_', 'blr', 'bctr', 'blrl', 'bctrl', 'crset', 'crclr', 'crmove',
+    'crnot', 'mt', 'mf','nop', 'li', 'la', 'mr','not', 'mtcr');
+
+{$ifdef GDB}
+      procedure talphaattasmlist.WriteFileLineInfo(var fileinfo : tfileposinfo);
+        var
+          curr_n : byte;
+        begin
+          if not (cs_debuginfo in aktmoduleswitches) then
+           exit;
+        { file changed ? (must be before line info) }
+          if (fileinfo.fileindex<>0) and
+             (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
+           begin
+             infile:=current_module^.sourcefiles^.get_file(fileinfo.fileindex);
+             if includecount=0 then
+              curr_n:=n_sourcefile
+             else
+              curr_n:=n_includefile;
+             if (infile^.path^<>'') then
+              begin
+                AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile^.path^,false)))+'",'+
+                  tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
+              end;
+             AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile^.name^))+'",'+
+               tostr(curr_n)+',0,0,'+'Ltext'+ToStr(IncludeCount));
+             AsmWriteLn('Ltext'+ToStr(IncludeCount)+':');
+             inc(includecount);
+           end;
+        { line changed ? }
+          if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
+           begin
+             if (n_line=n_textline) and assigned(funcname) and
+                (target_os.use_function_relative_addresses) then
+              begin
+                AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
+                AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
+                           target_asm.labelprefix+'l'+tostr(linecount)+' - ');
+                AsmWritePChar(FuncName);
+                AsmLn;
+                inc(linecount);
+              end
+             else
+              AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
+           end;
+          stabslastfileinfo:=fileinfo;
+        end;
+{$endif GDB}
+
+    procedure talphaattasmlist.WriteTree(p:paasmoutput);
+    const
+      allocstr : array[boolean] of string[10]=(' released',' allocated');
+    type
+      t64bitarray = array[0..7] of byte;
+      t32bitarray = array[0..3] of byte;
+    var
+      ch       : char;
+      hp       : pai;
+      consttyp : tait;
+      s        : string;
+      found    : boolean;
+      i,pos,l  : longint;
+      co       : comp;
+      sin      : single;
+      d        : double;
+      e        : extended;
+      op       : tasmop;
+      calljmp,
+      do_line  : boolean;
+      sep      : char;
+    begin
+      if not assigned(p) then
+       exit;
+      do_line:=(cs_debuginfo in aktmoduleswitches) or (cs_asm_source in aktglobalswitches);
+      hp:=pai(p^.first);
+      while assigned(hp) do
+       begin
+         aktfilepos:=hp^.fileinfo;
+         if do_line then
+          begin
+          { I think it is better to write stabs before source line PM }
+{$ifdef GDB}
+          { write stabs }
+            if cs_debuginfo in aktmoduleswitches then
+             begin
+               if not (hp^.typ in  [
+                      ait_label,
+                      ait_regalloc,ait_tempalloc,
+                      ait_stabn,ait_stabs,ait_section,
+                      ait_cut,ait_marker,ait_align,ait_stab_function_name]) then
+                 begin
+                    WriteFileLineInfo(hp^.fileinfo);
+                 end;
+             end;
+{$endif GDB}
+          { load infile }
+            if lastfileinfo.fileindex<>hp^.fileinfo.fileindex then
+             begin
+               infile:=current_module^.sourcefiles^.get_file(hp^.fileinfo.fileindex);
+               { open only if needed !! }
+               if (cs_asm_source in aktglobalswitches) then
+                 infile^.open;
+               { avoid unnecessary reopens of the same file !! }
+               lastfileinfo.fileindex:=hp^.fileinfo.fileindex;
+               { be sure to change line !! }
+               lastfileinfo.line:=-1;
+             end;
+          { write source }
+            if (cs_asm_source in aktglobalswitches) and
+                not (hp^.typ in  [
+                      ait_label,
+                      ait_stabn,ait_stabs,ait_section,
+                      ait_cut,ait_align,ait_stab_function_name]) then
+             begin
+               if (infile<>lastinfile) and assigned(lastinfile) then
+                 begin
+                   AsmWriteLn(target_asm.comment+'['+infile^.name^+']');
+                   lastinfile^.close;
+                 end;
+               if (hp^.fileinfo.line<>lastfileinfo.line) and
+                  (hp^.fileinfo.line<infile^.maxlinebuf) then
+                 begin
+                   if (hp^.fileinfo.line<>0) and
+                      (infile^.linebuf^[hp^.fileinfo.line]>=0) then
+                     AsmWriteLn(target_asm.comment+'['+tostr(hp^.fileinfo.line)+'] '+
+                       fixline(infile^.GetLineStr(hp^.fileinfo.line)));
+                   { set it to a negative value !
+                   to make that is has been read already !! PM }
+                   infile^.linebuf^[hp^.fileinfo.line]:=-infile^.linebuf^[hp^.fileinfo.line]-1;
+                end;
+               lastfileinfo:=hp^.fileinfo;
+               lastinfile:=infile;
+             end;
+          end;
+
+         case hp^.typ of
+
+           ait_comment :
+             Begin
+               AsmWrite(target_asm.comment);
+               AsmWritePChar(pai_asm_comment(hp)^.str);
+               AsmLn;
+             End;
+
+           ait_regalloc :
+             begin
+               if (cs_asm_regalloc in aktglobalswitches) then
+                 AsmWriteLn(target_asm.comment+'Register '+att_reg2str[pairegalloc(hp)^.reg]+
+                   allocstr[pairegalloc(hp)^.allocation]);
+             end;
+
+           ait_tempalloc :
+             begin
+               if (cs_asm_tempalloc in aktglobalswitches) then
+                 AsmWriteLn(target_asm.comment+'Temp '+tostr(paitempalloc(hp)^.temppos)+','+
+                   tostr(paitempalloc(hp)^.tempsize)+allocstr[paitempalloc(hp)^.allocation]);
+             end;
+
+           ait_align :
+             begin
+               AsmWrite(#9'.balign '+tostr(pai_align(hp)^.aligntype));
+               if pai_align(hp)^.use_op then
+                AsmWrite(','+tostr(pai_align(hp)^.fillop));
+               AsmLn;
+             end;
+
+           ait_section :
+             begin
+               if pai_section(hp)^.sec<>sec_none then
+                begin
+                  AsmLn;
+                  AsmWriteLn(ait_section2str(pai_section(hp)^.sec));
+{$ifdef GDB}
+                  lastfileinfo.line:=-1;
+{$endif GDB}
+                end;
+             end;
+
+           ait_datablock :
+             begin
+               if pai_datablock(hp)^.is_global then
+                AsmWrite(#9'.comm'#9)
+               else
+                AsmWrite(#9'.lcomm'#9);
+               AsmWrite(pai_datablock(hp)^.sym^.name);
+               AsmWriteLn(','+tostr(pai_datablock(hp)^.size));
+             end;
+
+           ait_const_32bit,
+           ait_const_16bit,
+           ait_const_8bit :
+             begin
+               AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
+               consttyp:=hp^.typ;
+               l:=0;
+               repeat
+                 found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
+                 if found then
+                  begin
+                    hp:=Pai(hp^.next);
+                    s:=','+tostr(pai_const(hp)^.value);
+                    AsmWrite(s);
+                    inc(l,length(s));
+                  end;
+               until (not found) or (l>line_length);
+               AsmLn;
+             end;
+
+           ait_const_symbol :
+             begin
+               AsmWrite(#9'.long'#9+pai_const_symbol(hp)^.sym^.name);
+               if pai_const_symbol(hp)^.offset>0 then
+                 AsmWrite('+'+tostr(pai_const_symbol(hp)^.offset))
+               else if pai_const_symbol(hp)^.offset<0 then
+                 AsmWrite(tostr(pai_const_symbol(hp)^.offset));
+               AsmLn;
+             end;
+
+           ait_const_rva :
+             AsmWriteLn(#9'.rva'#9+pai_const_symbol(hp)^.sym^.name);
+
+           ait_real_64bit :
+             begin
+               if do_line then
+                AsmWriteLn(target_asm.comment+double2str(pai_real_64bit(hp)^.value));
+               d:=pai_real_64bit(hp)^.value;
+               AsmWrite(#9'.byte'#9);
+               for i:=0 to 7 do
+                begin
+                  if i<>0 then
+                   AsmWrite(',');
+                  AsmWrite(tostr(t64bitarray(d)[i]));
+                end;
+               AsmLn;
+             end;
+
+           ait_real_32bit :
+             begin
+               if do_line then
+                AsmWriteLn(target_asm.comment+single2str(pai_real_32bit(hp)^.value));
+               sin:=pai_real_32bit(hp)^.value;
+               AsmWrite(#9'.byte'#9);
+               for i:=0 to 3 do
+                begin
+                  if i<>0 then
+                   AsmWrite(',');
+                  AsmWrite(tostr(t32bitarray(sin)[i]));
+                end;
+               AsmLn;
+             end;
+
+           ait_comp_64bit :
+             begin
+               if do_line then
+                AsmWriteLn(target_asm.comment+comp2str(pai_comp_64bit(hp)^.value));
+               AsmWrite(#9'.byte'#9);
+{$ifdef FPC}
+               co:=comp(pai_comp_64bit(hp)^.value);
+{$else}
+               co:=pai_comp_64bit(hp)^.value;
+{$endif}
+               for i:=0 to 7 do
+                begin
+                  if i<>0 then
+                   AsmWrite(',');
+                  AsmWrite(tostr(t64bitarray(co)[i]));
+                end;
+               AsmLn;
+             end;
+
+           ait_direct :
+             begin
+               AsmWritePChar(pai_direct(hp)^.str);
+               AsmLn;
+{$IfDef GDB}
+               if strpos(pai_direct(hp)^.str,'.data')<>nil then
+                 n_line:=n_dataline
+               else if strpos(pai_direct(hp)^.str,'.text')<>nil then
+                 n_line:=n_textline
+               else if strpos(pai_direct(hp)^.str,'.bss')<>nil then
+                 n_line:=n_bssline;
+{$endif GDB}
+             end;
+
+           ait_string :
+             begin
+               pos:=0;
+               for i:=1 to pai_string(hp)^.len do
+                begin
+                  if pos=0 then
+                   begin
+                     AsmWrite(#9'.ascii'#9'"');
+                     pos:=20;
+                   end;
+                  ch:=pai_string(hp)^.str[i-1];
+                  case ch of
+                     #0, {This can't be done by range, because a bug in FPC}
+                #1..#31,
+             #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
+                    '"' : s:='\"';
+                    '\' : s:='\\';
+                  else
+                   s:=ch;
+                  end;
+                  AsmWrite(s);
+                  inc(pos,length(s));
+                  if (pos>line_length) or (i=pai_string(hp)^.len) then
+                   begin
+                     AsmWriteLn('"');
+                     pos:=0;
+                   end;
+                end;
+             end;
+
+           ait_label :
+             begin
+               if (pai_label(hp)^.l^.is_used) then
+                begin
+                  if pai_label(hp)^.l^.typ=AS_GLOBAL then
+                    AsmWriteLn('.globl'#9+pai_label(hp)^.l^.name);
+                  AsmWriteLn(pai_label(hp)^.l^.name+':');
+                end;
+             end;
+
+           ait_symbol :
+             begin
+               if pai_symbol(hp)^.is_global then
+                AsmWriteLn('.globl'#9+pai_symbol(hp)^.sym^.name);
+               if target_info.target=target_i386_linux then
+                begin
+                   AsmWrite(#9'.type'#9+pai_symbol(hp)^.sym^.name);
+                   if assigned(pai(hp^.next)) and
+                      (pai(hp^.next)^.typ in [ait_const_symbol,ait_const_rva,
+                         ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_datablock,
+                         ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit]) then
+                    AsmWriteLn(',@object')
+                   else
+                    AsmWriteLn(',@function');
+                   if pai_symbol(hp)^.sym^.size>0 then
+                    AsmWriteLn(#9'.size'#9+pai_symbol(hp)^.sym^.name+', '+tostr(pai_symbol(hp)^.sym^.size));
+                end;
+               AsmWriteLn(pai_symbol(hp)^.sym^.name+':');
+             end;
+
+           ait_symbol_end :
+             begin
+               if target_info.target=target_i386_linux then
+                begin
+                  s:=target_asm.labelprefix+'e'+tostr(symendcount);
+                  inc(symendcount);
+                  AsmWriteLn(s+':');
+                  AsmWriteLn(#9'.size'#9+pai_symbol(hp)^.sym^.name+', '+s+' - '+pai_symbol(hp)^.sym^.name);
+                end;
+             end;
+
+           ait_instruction :
+             begin
+
+               op:=pai386(hp)^.opcode;
+               calljmp:=is_calljmp(op);
+             { call maybe not translated to calll }
+               s:=#9+att_op2str[op]+cond2str[pai386(hp)^.condition];
+               if (not calljmp) and
+                  (not att_nosuffix[op]) and
+                  not(
+                   (pai386(hp)^.oper[0].typ=top_reg) and
+                   (pai386(hp)^.oper[0].reg in [R_ST..R_ST7])
+                  ) then
+                s:=s+att_opsize2str[pai386(hp)^.opsize];
+             { process operands }
+               if pai386(hp)^.ops<>0 then
+                begin
+                { call and jmp need an extra handling                          }
+                { this code is only called if jmp isn't a labeled instruction }
+                  if calljmp then
+                   s:=s+#9+getopstr_jmp(pai386(hp)^.oper[0])
+                  else
+                   begin
+                     for i:=0to pai386(hp)^.ops-1 do
+                      begin
+                        if i=0 then
+                         sep:=#9
+                        else
+                         sep:=',';
+                        s:=s+sep+getopstr(pai386(hp)^.oper[i])
+                      end;
+                   end;
+                end;
+               AsmWriteLn(s);
+             end;
+
+{$ifdef GDB}
+           ait_stabs :
+             begin
+               AsmWrite(#9'.stabs ');
+               AsmWritePChar(pai_stabs(hp)^.str);
+               AsmLn;
+             end;
+
+           ait_stabn :
+             begin
+               AsmWrite(#9'.stabn ');
+               AsmWritePChar(pai_stabn(hp)^.str);
+               AsmLn;
+             end;
+
+           ait_force_line :
+             stabslastfileinfo.line:=0;
+
+           ait_stab_function_name:
+             funcname:=pai_stab_function_name(hp)^.str;
+{$endif GDB}
+
+           ait_cut :
+             begin
+               if SmartAsm then
+                begin
+                { only reset buffer if nothing has changed }
+                  if AsmSize=AsmStartSize then
+                   AsmClear
+                  else
+                   begin
+                     AsmClose;
+                     DoAssemble;
+                     if pai_cut(hp)^.EndName then
+                      IsEndFile:=true;
+                     AsmCreate;
+                   end;
+                { avoid empty files }
+                  while assigned(hp^.next) and (pai(hp^.next)^.typ in [ait_cut,ait_section,ait_comment]) do
+                   begin
+                     if pai(hp^.next)^.typ=ait_section then
+                       lastsec:=pai_section(hp^.next)^.sec;
+                     hp:=pai(hp^.next);
+                   end;
+{$ifdef GDB}
+                  { force write of filename }
+                  FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
+                  includecount:=0;
+                  funcname:=nil;
+                  WriteFileLineInfo(hp^.fileinfo);
+{$endif GDB}
+                  if lastsec<>sec_none then
+                    AsmWriteLn(ait_section2str(lastsec));
+                  AsmStartSize:=AsmSize;
+                end;
+             end;
+
+           ait_marker :
+             ;
+
+           else
+             internalerror(10000);
+         end;
+         hp:=pai(hp^.next);
+       end;
+    end;
+
+
+    procedure talphaattasmlist.WriteAsmList;
+    var
+      p:dirstr;
+      n:namestr;
+      e:extstr;
+{$ifdef GDB}
+      fileinfo : tfileposinfo;
+{$endif GDB}
+
+    begin
+{$ifdef EXTDEBUG}
+      if assigned(current_module^.mainsource) then
+       Comment(v_info,'Start writing GNU-styled assembler output for '+current_module^.mainsource^);
+{$endif}
+
+      LastSec:=sec_none;
+{$ifdef GDB}
+      FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
+{$endif GDB}
+      FillChar(lastfileinfo,sizeof(lastfileinfo),0);
+      LastInfile:=nil;
+
+      if assigned(current_module^.mainsource) then
+       fsplit(current_module^.mainsource^,p,n,e)
+      else
+       begin
+         p:=inputdir;
+         n:=inputfile;
+         e:=inputextension;
+       end;
+    { to get symify to work }
+      AsmWriteLn(#9'.file "'+FixFileName(n+e)+'"');
+
+{$ifdef GDB}
+      n_line:=n_bssline;
+      funcname:=nil;
+      linecount:=1;
+      includecount:=0;
+      fileinfo.fileindex:=1;
+      fileinfo.line:=1;
+      { Write main file }
+      WriteFileLineInfo(fileinfo);
+{$endif GDB}
+      AsmStartSize:=AsmSize;
+      symendcount:=0;
+
+      countlabelref:=false;
+      If (cs_debuginfo in aktmoduleswitches) then
+        WriteTree(debuglist);
+      WriteTree(codesegment);
+      WriteTree(datasegment);
+      WriteTree(consts);
+      WriteTree(rttilist);
+      Writetree(resourcestringlist);
+      WriteTree(bsssegment);
+      Writetree(importssection);
+      Writetree(exportssection);
+      Writetree(resourcesection);
+      countlabelref:=true;
+
+      AsmLn;
+{$ifdef EXTDEBUG}
+      if assigned(current_module^.mainsource) then
+       comment(v_info,'Done writing att-styled assembler output for '+current_module^.mainsource^);
+{$endif EXTDEBUG}
+    end;
+
+
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-03 23:37:52  jonas
+    + initial implementation for PowerPC based on the Alpha stuff
+
+}

+ 338 - 0
compiler/new/powerpc/cpuasm.pas

@@ -0,0 +1,338 @@
+{
+    $Id$
+    Copyright (c) 1999 by Florian Klaempfl
+
+    Contains the assembler object for the PowerPC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpuasm;
+
+interface
+
+uses
+  cobjects,
+  aasm,globals,verbose,
+  cpubase;
+
+type
+  pairegalloc = ^tairegalloc;
+  tairegalloc = object(tai)
+     allocation : boolean;
+     reg        : tregister;
+     constructor alloc(r : tregister);
+     constructor dealloc(r : tregister);
+  end;
+
+  pappc = ^tappc;
+  tappc = object(tai)
+     is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
+     opcode    : tasmop;
+     ops       : longint;
+     condition : TasmCond;
+     oper      : array[0..4] of toper;
+
+     constructor op_none(op : tasmop);
+
+     constructor op_reg(op : tasmop;_op1 : tregister);
+     constructor op_const(op : tasmop;_op1 : longint);
+
+     constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+     constructor op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
+     constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
+     constructor op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
+
+     constructor op_const_const(op : tasmop;_op1,_op2 : longint);
+
+     constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+     constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+     constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: pasmsymbol;_op3ofs: longint);
+     constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+     constructor op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
+     constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
+
+     constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+     constructor op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
+     constructor op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
+
+     constructor op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
+
+
+     { this is for Jmp instructions }
+     constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : pasmsymbol);
+     constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint);
+
+
+     constructor op_sym(op : tasmop;_op1 : pasmsymbol);
+     constructor op_sym_ofs(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint);
+     constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:pasmsymbol;_op2ofs : longint);
+
+     destructor done;virtual;
+     function  getcopy:plinkedlist_item;virtual;
+  private
+     segprefix : tregister;
+     procedure init(op : tasmop); { this need to be called by all constructor }
+  end;
+
+
+implementation
+uses
+  og386;
+
+{*****************************************************************************
+                                 TaiRegAlloc
+*****************************************************************************}
+
+    constructor tairegalloc.alloc(r : tregister);
+      begin
+        inherited init;
+        typ:=ait_regalloc;
+        allocation:=true;
+        reg:=r;
+      end;
+
+
+    constructor tairegalloc.dealloc(r : tregister);
+      begin
+        inherited init;
+        typ:=ait_regalloc;
+        allocation:=false;
+        reg:=r;
+      end;
+
+
+{*****************************************************************************
+                                 tappc Constructors
+*****************************************************************************}
+
+    procedure tappc.init(op : tasmop);
+      begin
+         typ:=ait_instruction;
+         is_jmp:=false;
+         segprefix:=R_NO;
+         opcode:=op;
+         ops:=0;
+         condition:=c_none;
+         fillchar(oper,sizeof(oper),0);
+      end;
+
+    constructor tappc.op_none(op : tasmop);
+      begin
+         inherited init;
+         init(op);
+      end;
+
+
+    constructor tappc.op_reg(op : tasmop;_op1 : tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=1;
+      end;
+
+
+    constructor tappc.op_const(op : tasmop;_op1 : longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=1;
+      end;
+
+
+    constructor tappc.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+    constructor tappc.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+     constructor op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+
+    constructor tappc.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+
+    constructor tappc.op_const_const(op : tasmop;_op1,_op2 : longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+
+    constructor tappc.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=3;
+      end;
+
+     constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+       begin
+         inherited init;
+         init(op);
+         ops:=3;
+      end;
+
+     constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: pasmsymbol;_op3ofs: longint);
+       begin
+         inherited init;
+         init(op);
+         ops:=3;
+      end;
+
+    constructor tappc.op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=3;
+      end;
+
+     constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=3;
+      end;
+
+
+     constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=4;
+      end;
+
+     constructor op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
+      begin
+         inherited init;
+         init(op);
+         ops:=4;
+      end;
+
+     constructor op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=4;
+      end;
+
+     constructor op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=5;
+      end;
+
+    constructor tappc.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : pasmsymbol);
+      begin
+         inherited init;
+         init(op);
+         condition:=cond;
+         ops:=1;
+      end;
+
+     constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint);
+      begin
+         inherited init;
+         init(op);
+         condition:=cond;
+         ops:=3;
+      end;
+
+
+    constructor tappc.op_sym(op : tasmop;_op1 : pasmsymbol);
+      begin
+         inherited init;
+         init(op);
+         ops:=1;
+      end;
+
+
+    constructor tappc.op_sym_ofs(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=1;
+      end;
+
+
+     constructor tappc.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:pasmsymbol;_op2ofs : longint);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+
+    constructor tappc.op_sym_ofs_ref(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
+      begin
+         inherited init;
+         init(op);
+         ops:=2;
+      end;
+
+    destructor tappc.done;
+      var
+        i : longint;
+      begin
+          for i:=1 to ops do
+            if (oper[i-1].typ=top_ref) then
+              dispose(oper[i-1].ref);
+        inherited done;
+      end;
+
+    function tappc.getcopy:plinkedlist_item;
+      var
+        i : longint;
+        p : plinkedlist_item;
+      begin
+        p:=inherited getcopy;
+        { make a copy of the references }
+        for i:=1 to ops do
+         if (paalpha(p)^.oper[i-1].typ=top_ref) then
+          begin
+            new(paalpha(p)^.oper[i-1].ref);
+            paalpha(p)^.oper[i-1].ref^:=oper[i-1].ref^;
+          end;
+        getcopy:=p;
+      end;
+
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-03 23:37:53  jonas
+    + initial implementation for PowerPC based on the Alpha stuff
+
+}

+ 459 - 0
compiler/new/powerpc/cpubase.pas

@@ -0,0 +1,459 @@
+{
+    $Id$
+    Copyright (c) 1999 by Florian Klaempfl
+
+    Contains the base types for the PowerPC
+
+    * This code was inspired by the NASM sources
+      The Netwide Assembler is copyright (C) 1996 Simon Tatham and
+      Julian Hall. All rights reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpubase;
+interface
+{$ifdef TP}
+  {$L-,Y-}
+{$endif}
+
+uses
+  strings,cobjects,aasm;
+
+const
+{ Size of the instruction table converted by nasmconv.pas }
+  instabentries = 1103;
+  maxinfolen    = 7;
+
+{ By default we want everything }
+{$define ATTOP}
+{$define ATTREG}
+{$define INTELOP}
+{$define ITTABLE}
+
+{ For TP we can't use asmdebug due the table sizes }
+{$ifndef TP}
+  {$define ASMDEBUG}
+{$endif}
+
+{ We Don't need the intel style opcodes if we don't have a intel
+  reader or generator }
+{$ifndef ASMDEBUG}
+{$ifdef NORA386INT}
+  {$ifdef NOAG386NSM}
+    {$ifdef NOAG386INT}
+      {$undef INTELOP}
+    {$endif}
+  {$endif}
+{$endif}
+{$endif}
+
+{ We Don't need the AT&T style opcodes if we don't have a AT&T
+  reader or generator }
+{$ifdef NORA386ATT}
+  {$ifdef NOAG386ATT}
+    {$undef ATTOP}
+    {$ifdef NOAG386DIR}
+       {$undef ATTREG}
+    {$endif}
+  {$endif}
+{$endif}
+
+type
+  TAsmOp=(A_None,
+    { normal opcodes }
+    a_add, a_add_, a_addo, a_addo_, a_addc, a_addc_, a_addco, a_addco_,
+    a_adde, a_adde_, a_addeo, a_addeo_, a_addi, a_addic, a_addic_, a_addis,
+    a_addme, a_addme_, a_addmeo, a_addmeo_, a_addze, a_addze_, a_addzeo,
+    a_addzeo_, a_and, a_and_, a_andc, a_andc_, a_andi_, a_andis_, a_b,
+    a_ba, a_bl, a_bla, a_bc, a_bca, a_bcl, a_bcla, a_bcctr, a_bcctrl, a_bclr,
+    a_bclrl, a_cmp, a_cmpi, a_cmpl, a_cmpli, a_cntlzw, a_cntlzw_, a_crand,
+    a_crandc, a_creqv, a_crnand, a_crnor, a_cror, a_crorc, a_crxor, a_dcba,
+    a_dcbf, a_dcbi, a_dcbst, a_dcbt, a_divw, a_divw_, a_divwo, a_divwo_,
+    a_divwu, a_divwu_, a_divwuo, a_divwuo_, a_eciwx, a_ecowx, a_eieio, a_eqv,
+    a_eqv_, a_extsb, a_extsb_, a_extsh, a_extsh_, a_fabs, a_fabs_, a_fadd,
+    a_fadd_, a_fadds, a_fadds_, a_fcompo, a_fcmpu, a_fctiw, a_fctw_, a_fctwz,
+    a_fctwz_, a_fdiv, a_fdiv_, a_fdivs, a_fdivs_, a_fmadd, a_fmadd_, a_fmadds,
+    a_fmadds_, a_fmr, a_fmsub, a_fmsub_, a_fmsubs, a_fmsubs_, a_fmul, a_fmul_,
+    a_fmuls, a_fmuls_, a_fnabs, a_fnabs_, a_fneg, a_fneg_, a_fnmadd,
+    a_fnmadd_, a_fnmadds, a_fnmadds_, a_fnmsub, a_fnmsub_, a_fnmsubs,
+    a_fnmsubs_, a_fres, a_fres_, a_frsp, a_frsp_, a_frsqrte, a_frsqrte_,
+    a_fsel, a_fsel_, a_fsqrt, a_fsqrt_, a_fsqrts, a_fsqrts_, a_fsub, a_fsub_,
+    a_fsubs, a_fsubs_, a_icbi, a_isync, a_lbz, a_lbzu, a_lbzux, a_lbzx,
+    a_lfd, a_lfdu, a_lfdux, a_lfdx, a_lfs, a_lfsu, a_lfsux, a_lfsx, a_lha,
+    a_lhau, a_lhaux, a_lhax, a_hbrx, a_lhz, a_lhzu, a_lhzux, a_lhzx, a_lmw,
+    a_lswi, a_lswx, a_lwarx, a_lwbrx, a_lwz, a_lwzu, a_lwzux, a_lwzx, a_mcrf,
+    a_mcrfs, a_lcrxe, a_mfcr, a_mffs, a_maffs_, a_mfmsr, a_mfspr, a_mfsr,
+    a_mfsrin, a_mftb, a_mtfcrf, a_a_mtfd0, a_mtfsb1, a_mtfsf, a_mtfsf_,
+    a_mtfsfi, a_mtfsfi_, a_mtmsr, a_mtspr, a_mtsr, a_mtsrin, a_mulhw,
+    a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullh, a_mullw_, a_mullwo,
+    a_mullwo_, a_nand, a_nand_, a_neg, a_neg_, a_nego, a_nego_, a_nor, a_nor_,
+    a_or, a_or_, a_orc, a_orc_, a_ori, a_oris, a_rfi, a_rlwimi, a_rlwimi_,
+    a_rlwinm, a_tlwinm_, a_rlwnm, a_sc, a_slw, a_slw_, a_sraw, a_sraw_,
+    a_srawi, a_srawi_,a_srw, a_srw_, a_stb, a_stbu, a_stbux, a_a_stbx, a_stfd,
+    a_stfdu, a_stfdux, a_stfdx, a_stfiwx, a_stfs, a_stfsu, a_stfsux, a_stfsx,
+    a_sth, a_sthbrx, a_sthu, a_sthux, a_sthx, a_stmw, a_stswi, a_stswx, a_stw,
+    a_stwbrx, a_stwx_, a_stwu, a_stwux, a_stwx, a_subf, a_subf_, a_subfo,
+    a_subfo_, a_subfc, a_subc_, a_subfco, a_subfco_, a_subfe, a_subfe_,
+    a_subfeo, a_subfeo_, a_subfic, a_subfme, a_subfme_, a_subfmeo, a_subfmeo_,
+    a_subfze, a_subfze_, a_subfzeo, a_subfzeo_, a_sync, a_tlbia, a_tlbie,
+    a_tlbsync, a_tw, twi, a_xor, a_xor_, a_xori, a_xoris,
+    { simplified mnemonics }
+    a_subi, a_subis, a_subic, a_subic_, a_sub, a_sub_, a_subo, a_subo_,
+    a_subc, a_subc_, a_subco, _subco_, a_cmpwi, a_cmpw, a_cmplwi, a_cmplw,
+    a_extlwi, a_extlwi_, a_extrwi, a_extrwi_, a_inslwi, a_inslwi_, a_insrwi,
+    a_insrwi_, a_rotlwi, a_rotlwi_, a_rotlw, a_rotlw_, a_slwi, a_slwi_,
+    a_srwi, a_srwi_, a_clrlwi, a_clrlwi_, a_clrrwi, a_clrrwi_, a_clrslwi,
+    a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove,
+    a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
+    nop, a_li, a_la, a_mr, a_not, a_mtcr);
+
+  op2strtable=array[tasmop] of string[8];
+
+const
+  firstop = low(tasmop);
+  lastop  = high(tasmop);
+
+
+{*****************************************************************************
+                                Conditions
+*****************************************************************************}
+
+(* still needs to be implmented in a generic way somehow
+
+type
+  TAsmCond=(C_None,
+    C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU
+  );
+
+  TAsmCondBO = (B_T,B_F,B_DNZ,B_DNZT,B_DNZF,B_DZ,B_DZT,B_DZF);
+  TasmCondSuffix = (SU_NO,SU_A,SU_LR,SU_CTR,SU_L,SU_LA,SU_LRL,SU_CTRL);
+
+const
+  cond2str:array[TAsmCond] of string[2]=('',
+    'lt','le','eq','ge','gt','nl','ne','ng','so','ns','un','nu'
+  );
+
+  condbo2str:array[TasmCondBO] of String[4] = (
+    't','f','dnz','dnzt','dnzf','dz','dzt','dzf'
+  );
+
+  condsuffix2str:array[TAsmCondSuffix] of String[4] = (
+    '','a','lr','ctr','l','la','lrl','ctrl'
+  );
+
+  inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
+    C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN
+  );
+
+  AllowedCond = Array[TAsmCondBO,TAsmCondSuffix] of Boolean = (
+{t}      (
+{f}
+{dnz}
+{dnzt}
+{dnzf}
+{dz}
+{dzt}
+{dzf}
+const
+  CondAsmOps=3;
+  CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
+     A_BC, A_TW, A_TWI
+  );
+*)
+
+{*****************************************************************************
+                                  Registers
+*****************************************************************************}
+
+type
+  { enumeration for registers, don't change the order }
+  { it's used by the register size conversions        }
+  tregister = (R_NO,
+    R_0,R_1,R_2,R_3,R_4,R_5,R_6,R_7, R_9,R_10,R_11,R_12,R_13,R_14,R_15,R_16,
+    R_17,R_18,R_19,R_20,R_21,R_22,R_23,R_24,R_25,R_26,R_27,R_28,R_29,R_30,R_31,
+    R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,
+    R_F13,R_F14,R_F15,R_F16,R_F17, R_F18,R_F19,R_F20,R_F21,R_F22, R_F23,R_F24,
+    R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31,
+    R_M0,R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,
+    R_M13,R_M14,R_M15,R_M16,R_M17,R_M18,R_M19,R_M20,R_M21,R_M22, R_M23,R_M24,
+    R_M25,R_M26,R_M27,R_M28,R_M29,R_M30,R_M31,
+
+    R_CR,R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7,
+    R_XER,R_LR,R_CTR,R_FPSCR
+  );
+
+Const
+   R_SPR1 = R_XER;
+   R_SPR8 = R_LR;
+   R_SPR9 = R_CTR;
+   R_TOC = R_2;
+   CR0 = 0;
+   CR1 = 4;
+   CR2 = 8;
+   CR3 = 12;
+   CR4 = 16;
+   CR5 = 20;
+   CR6 = 24;
+   CR7 = 28;
+   LT = 0;
+   GT = 1;
+   EQ = 2;
+   SO = 3;
+   FX = 4;
+   FEX = 5;
+   VX = 6;
+   OX = 7;
+
+
+Type
+  tregisterset = set of tregister;
+
+  reg2strtable = array[tregister] of string[5];
+
+const
+  firstreg = low(tregister);
+  lastreg  = high(tregister);
+
+  gnu_reg2str : reg2strtable = ('',
+    '0','1','2','3','4','5','6','7', '9','10','11','12','13','14','15','16',
+    '17','18','19','20','21','22','23','24','25','26','27','28','29','30','31',
+    'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
+    'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
+    'F25','F26','F27','F28','F29','F30','F31',
+    'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
+    'XER','LR','CTR','FPSCR'
+  );
+
+  mot_reg2str : reg2strtable = ('',
+    'R0','R1','R2','R3','R4','R5','R6','R7', 'R9','R10','R11','R12','R13',
+    'R14','R15','R16','R17','R18','R19','R20','R21','R22','R23','R24','R25',
+    'R26','R27','R28','R29','R30','R31',
+    'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
+    'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
+    'F25','F26','F27','F28','F29','F30','F31',
+    'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
+    'XER','LR','CTR','FPSCR'
+  );
+
+
+{*****************************************************************************
+                                   Flags
+*****************************************************************************}
+
+type
+  TResFlags = (F_LT,F_GT,F_EQ,F_SO,F_FX,F_FEX,F_VX,F_OX);
+
+const
+  { arrays for boolean location conversions }
+  flag_2_cond : array[TResFlags] of TAsmCond =
+     (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
+
+
+{*****************************************************************************
+                                Reference
+*****************************************************************************}
+
+type
+  trefoptions=(ref_none,ref_parafixup,ref_localfixup);
+
+  { immediate/reference record }
+  preference = ^treference;
+  treference = packed record
+     is_immediate : boolean; { is this used as reference or immediate }
+     base: tregister;
+     offset      : longint;
+     symbol      : pasmsymbol;
+     offsetfixup : longint;
+     options     : trefoptions;
+  end;
+
+
+{*****************************************************************************
+                                Operand
+*****************************************************************************}
+
+type
+  toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
+
+  toper=record
+    ot  : longint;
+    case typ : toptype of
+     top_none   : ();
+     top_reg    : (reg:tregister);
+     top_ref    : (ref:preference);
+     top_const  : (val:longint);
+     top_symbol : (sym:pasmsymbol;symofs:longint);
+  end;
+
+
+{*****************************************************************************
+                               Generic Location
+*****************************************************************************}
+
+type
+  TLoc=(
+    LOC_INVALID,     { added for tracking problems}
+    LOC_REGISTER,    { in a processor register }
+    LOC_CREGISTER    { Constant register which shouldn't be modified }
+    LOC_FPUREGISTER, { FPU register }
+    LOC_CFPUREGISTER,{ Constant FPU register which shouldn't be modified }
+    LOC_MMREGISTER,  { multimedia register }
+    LOC_CMMREGISTER, { Constant multimedia reg which shouldn't be modified }
+    LOC_MEM,         { in memory }
+    LOC_REFERENCE,   { like LOC_MEM, but lvalue }
+    LOC_JUMP,        { boolean results only, jump to false or true label }
+    LOC_FLAGS,       { boolean results only, flags are set }
+  );
+
+  plocation = ^tlocation;
+  tlocation = packed record
+     case loc : tloc of
+        LOC_MEM,LOC_REFERENCE : (reference : treference);
+        LOC_FPUREGISTER, LOC_CFPUREGISTER : (register: tregister);
+        LOC_MMREGISTER, LOC_CMMREGISTER : (register: tregister);
+        LOC_JUMP : ();
+        LOC_FLAGS : (resflags : tresflags);
+        LOC_INVALID : ();
+
+        { segment in reference at the same place as in loc_register }
+        LOC_REGISTER,LOC_CREGISTER : (
+        case longint of
+          1 : (register,registerhigh : tregister);
+          { overlay a registerlow }
+          2 : (registerlow : tregister);
+        );
+  end;
+
+
+{*****************************************************************************
+                                 Constants
+*****************************************************************************}
+
+{type
+  tcpuflags = (cf_registers64);}
+
+const
+  availabletempregsint = [R_0,R_11..R_30];
+  availabletempregsfpu = [F_14..F_31];
+  availabletempregsmm  = [M_0..M_31];
+
+  intregs = [R_0..R_31];
+  fpuregs = [R_F0..R_F31];
+  mmregs = [R_M0..R_M31];
+
+  registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
+
+  { generic register names }
+  stack_pointer = R_1;
+  frame_pointer = R_31;
+  self_pointer  = R_9;
+  accumulator   = R_3;
+
+  cpuflags : set of tcpuflags = [];
+
+  { sizes }
+  pointersize   = 4;
+  extended_size = 8;
+
+{*****************************************************************************
+                                  Helpers
+*****************************************************************************}
+
+    { resets all values of ref to defaults }
+    procedure reset_reference(var ref : treference);
+    { set mostly used values of a new reference }
+    function new_reference(base : tregister;offset : longint) : preference;
+
+    function newreference(const r : treference) : preference;
+    procedure disposereference(var r : preference);
+
+    function reg2str(r : tregister) : string;
+
+    function is_calljmp(o:tasmop):boolean;
+
+
+implementation
+
+{$ifdef heaptrc}
+  uses
+      ppheap;
+{$endif heaptrc}
+
+{*****************************************************************************
+                                  Helpers
+*****************************************************************************}
+
+    function reg2str(r : tregister) : string;
+      begin
+         reg2str:=mot_reg2str[r];
+      end;
+
+
+    function is_calljmp(o:tasmop):boolean;
+      begin
+        case o of
+          A_B,
+          A_BA,
+          A_BLR,
+          A_BCTR,
+          A_BC:
+            is_calljmp:=true;
+          else
+            is_calljmp:=false;
+        end;
+      end;
+
+
+    procedure disposereference(var r : preference);
+      begin
+         dispose(r);
+         r:=nil;
+      end;
+
+
+    function newreference(const r : treference) : preference;
+      var
+         p : preference;
+      begin
+         new(p);
+         p^:=r;
+         newreference:=p;
+      end;
+
+procedure reset_reference(var ref : treference);
+begin
+  FillChar(ref,sizeof(treference),0);
+end;
+
+function new_reference(base : tregister;offset : longint) : preference;
+var
+  r : preference;
+begin
+  new(r);
+  FillChar(r^,sizeof(treference),0);
+  r^.base:=base;
+  r^.offset:=offset;
+  new_reference:=r;
+end;
+
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-03 23:37:53  jonas
+    + initial implementation for PowerPC based on the Alpha stuff
+
+}

+ 34 - 0
compiler/new/powerpc/cpuinfo.pas

@@ -0,0 +1,34 @@
+{
+    $Id$
+    Copyright (c) 1999 by the Free Pascal development team
+
+    Basic Processor information
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+Unit CPUInfo;
+
+Interface
+
+Type
+   { Architecture word - Native unsigned type }
+{$ifdef FPC}
+   AWord = Dword;
+{$else FPC}
+   AWord = Longint;
+{$endif FPC}
+
+Const
+   { Size of native extended type }
+   extended_size = 8;
+
+Implementation
+
+end.

+ 49 - 0
compiler/new/powerpc/tgcpu.pas

@@ -0,0 +1,49 @@
+{
+    $Id$
+    Copyright (C) 1993-99 by Florian Klaempfl
+
+    This unit handles the temporary variables stuff for PowerPC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit tgcpu;
+
+  interface
+
+    uses
+       tgobj;
+
+    type
+
+       ttgpowerpc = Object(ttgobj)
+       end;
+
+    var
+       tg : ttgppc;
+
+implementation
+
+begin
+  tg.init;
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-03 23:37:53  jonas
+    + initial implementation for PowerPC based on the Alpha stuff
+
+
+}