summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Worksheet28
-rw-r--r--mcon.c1670
-rw-r--r--mcon.h16
-rw-r--r--mfileIO3.c2718
-rw-r--r--mwrite_heap.c237
-rw-r--r--pcompact.a1762
-rw-r--r--pcopy.a1000
-rw-r--r--pfileIO3.a1428
-rw-r--r--pmacros.a54
-rw-r--r--pmark.a2316
-rw-r--r--pprofile.a1407
-rw-r--r--pstartup.a6085
-rw-r--r--ptrace.a676
13 files changed, 19397 insertions, 0 deletions
diff --git a/Worksheet b/Worksheet
new file mode 100644
index 0000000..5ddf528
--- /dev/null
+++ b/Worksheet
@@ -0,0 +1,28 @@
+
+Set -e CIncludes 'Programs:Metrowerks CodeWarrior 6.0:Metrowerks CodeWarrior:Carbon Support:Universal Interfaces:CIncludes,Programs:MPW:Interfaces:CIncludes'
+
+mrc -w off -sym off -d POWER -d G_POWER -d WRITE_HEAP mcon.c -o mcon.c.x
+mrc -sym off -d POWER -d G_POWER mwrite_heap.c -o mwrite_heap.c.x
+ppcasm -sym off -d PROFILE=0 -d LINUX=0 -typecheck pstartup.a -o pstartup.a.o
+PPCLink -sym off -xm library mcon.c.x mwrite_heap.c.x pstartup.a.o -o _startup.o
+setfile -t CgOb -c 3PRM _startup.o
+
+mrc -w off -sym off -d POWER -d G_POWER -d WRITE_HEAP -d TIME_PROFILE -d LINUX=0 mcon.c -o mcon.c.x
+ppcasm -sym off -d PROFILE=1 -d LINUX=0 -typecheck pstartup.a -o pstartup.a.o
+ppcasm -d POWER601=0 -d LINUX=0 -sym off -typecheck pprofile.a -o pprofile.a.o
+PPCLink -sym off -xm library mcon.c.x mwrite_heap.c.x pprofile.a.o pstartup.a.o -o _startupProfile.o
+setfile -t CgOb -c 3PRM _startupProfile.o
+
+ppcasm -d POWER601=1 -sym off -typecheck pprofile.a -o pprofile.a.o
+PPCLink -sym off -xm library mcon.c.x mwrite_heap.c.x pprofile.a.o pstartup.a.o -o _startupProfile601.o
+setfile -t CgOb -c 3PRM _startupProfile601.o
+
+ppcasm -sym off -typecheck ptrace.a -o ptrace.a.o
+PPCLink -sym off -xm library mcon.c.x mwrite_heap.c.x ptrace.a.o pstartup.a.o -o _startupTrace.o
+setfile -t CgOb -c 3PRM _startupTrace.o
+
+
+mrc -typecheck relaxed -w off -sym off -d POWER -d G_POWER mfileIO3.c
+ppcasm -sym off -typecheck pfileIO3.a -o pfileIO3.a.o
+PPCLink -sym off -xm library pfileIO3.a.o mfileIO3.c.o -o _library.o
+setfile -t CgOb -c 3PRM _library.o
diff --git a/mcon.c b/mcon.c
new file mode 100644
index 0000000..add8c69
--- /dev/null
+++ b/mcon.c
@@ -0,0 +1,1670 @@
+/*
+ File: mcon.c
+ Written by: John van Groningen
+*/
+
+#define MACOSX
+#define NEW_HEADERS
+#define G_POWER
+#define FLUSH_PORT_BUFFER
+
+#ifdef MACHO
+# define NEWLINE_CHAR '\r'
+#else
+# define NEWLINE_CHAR '\n'
+#endif
+
+#ifdef NEW_HEADERS
+# define TARGET_API_MAC_CARBON 1
+#endif
+
+#ifndef NEW_HEADERS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#else
+# ifndef MACHO
+extern void sprintf (char *,...);
+# endif
+#endif
+
+#define MULW(a,b) ((int)((short)(a)*(short)(b)))
+#define UDIVW(a,b) ((unsigned short)((unsigned short)(a)/(unsigned short)(b)))
+
+#include <quickdraw.h>
+#include <fonts.h>
+#include <events.h>
+#include <windows.h>
+#ifndef NEW_HEADERS
+# include <desk.h>
+#endif
+#include <memory.h>
+#include <resources.h>
+#include <menus.h>
+#include <OSUtils.h>
+#ifndef NEW_HEADERS
+# include <OSEvents.h>
+#endif
+
+#ifdef MACOSX
+# undef GetWindowPort
+#endif
+
+#undef PARALLEL
+#undef SIMULATE
+#undef COMMUNICATION
+
+#include "mcon.h"
+#ifdef COMMUNICATION
+# include "mcom.h"
+#endif
+
+#ifdef G_POWER
+void first_function (void)
+{
+}
+#endif
+
+extern void *abc_main();
+
+extern void add_IO_time(),add_execute_time();
+
+#define CONSOLE_WINDOW_ID 128
+#define ERROR_WINDOW_ID 129
+
+static int cur_y,cur_x;
+static int g_cur_x;
+static int n_screen_lines;
+
+static int e_cur_y,e_cur_x;
+static int e_g_cur_x;
+static int n_e_screen_lines;
+
+static int char_height,char_ascent,char_descent,char_leading,char_asc_lead;
+
+#define MAX_N_COLUMNS 160
+
+typedef char SCREEN_LINE_CHARS [MAX_N_COLUMNS+1];
+static SCREEN_LINE_CHARS *screen_chars,*e_screen_chars;
+
+static char *input_buffer;
+static int input_buffer_pos,input_buffer_length;
+
+static WindowPtr c_window,e_window;
+
+static int error_window_visible;
+static int console_window_visible;
+
+static EventRecord my_event;
+
+static void update_window (WindowPtr window,SCREEN_LINE_CHARS *chars,int n_lines,int g_cur_x,int cur_y)
+{
+ int y,screen_y_pos;
+ GrafPtr old_port;
+
+ BeginUpdate (window);
+ GetPort(&old_port);
+
+#ifdef MACOSX
+ SetPort (GetWindowPort (window));
+ {
+ RgnHandle visible_region;
+
+ visible_region=NewRgn();
+ GetPortVisibleRegion (GetWindowPort (window),visible_region);
+ EraseRgn (visible_region);
+ DisposeRgn (visible_region);
+ }
+#else
+ SetPort (window);
+ EraseRgn (window->visRgn);
+#endif
+
+ for (y=0,screen_y_pos=char_asc_lead; y<n_lines; ++y,screen_y_pos+=char_height){
+ char *line_chars,*c_p;
+ int line_length;
+
+ MoveTo (0,screen_y_pos);
+ line_chars=chars[y];
+
+ line_length=0;
+ c_p=line_chars;
+ while (*c_p++!=NEWLINE_CHAR)
+ ++line_length;
+ DrawText (line_chars,0,line_length);
+ }
+
+ MoveTo (g_cur_x,MULW (cur_y,char_height)+char_asc_lead);
+
+ SetPort (old_port);
+ EndUpdate (window);
+}
+
+static void select_window (WindowPtr window)
+{
+ if (window!=c_window && window!=e_window)
+ return;
+
+ SelectWindow (window);
+}
+
+static int c_window_width,c_window_height,e_window_width,e_window_height;
+
+static Rect c_window_rect,e_window_rect;
+static Rect c_local_window_rect,e_local_window_rect;
+
+static void scroll_window (WindowPtr window,SCREEN_LINE_CHARS *chars,int n_lines)
+{
+ RgnHandle erase_region;
+#ifdef MACOSX
+ Rect rect;
+#endif
+
+ add_execute_time();
+
+ erase_region=NewRgn();
+
+#ifdef MACOSX
+ GetPortBounds (GetWindowPort (window),&rect);
+ ScrollRect (&rect,0,-char_height,erase_region);
+#else
+ ScrollRect (&window->portRect,0,-char_height,erase_region);
+#endif
+
+ EraseRgn (erase_region);
+ DisposeRgn (erase_region);
+
+ BlockMove ((char*)chars[1],(char*)chars,(MAX_N_COLUMNS+1)*(n_lines-1));
+ chars[n_lines-1][0]=NEWLINE_CHAR;
+
+#ifdef FLUSH_PORT_BUFFER
+ QDFlushPortBuffer (GetWindowPort (window),NULL);
+#endif
+
+ add_IO_time();
+}
+
+static void print_newline()
+{
+ screen_chars[cur_y][cur_x]=NEWLINE_CHAR;
+ ++cur_y;
+ cur_x=0;
+ g_cur_x=0;
+ if (cur_y>=n_screen_lines){
+ cur_y=n_screen_lines-1;
+ scroll_window (c_window,screen_chars,n_screen_lines);
+ }
+#ifdef FLUSH_PORT_BUFFER
+ else
+ QDFlushPortBuffer (GetWindowPort (c_window),NULL);
+#endif
+ MoveTo (0,MULW(cur_y,char_height)+char_asc_lead);
+}
+
+static void window_print_char (char c)
+{
+ if (c==NEWLINE_CHAR)
+ print_newline();
+ else {
+ char *screen_char;
+ int w;
+
+ w=CharWidth (c);
+ if (g_cur_x+w>=c_window_width || cur_x+1>=MAX_N_COLUMNS)
+ print_newline();
+ g_cur_x+=w;
+
+ screen_char=&screen_chars[cur_y][cur_x];
+ *screen_char=c;
+ screen_char[1]=NEWLINE_CHAR;
+ DrawChar (c);
+ ++cur_x;
+ }
+}
+
+static void make_error_window_visible ()
+{
+ if (!error_window_visible){
+ add_execute_time();
+ ShowWindow (e_window);
+#ifdef MACOSX
+ ValidWindowRect (e_window,&e_local_window_rect);
+#else
+ ValidRect (&e_local_window_rect);
+#endif
+ add_IO_time();
+ error_window_visible=1;
+ }
+}
+
+static void make_console_window_visible ()
+{
+ if (!console_window_visible){
+ add_execute_time();
+
+ ShowWindow (c_window);
+
+#ifdef MACOSX
+ ValidWindowRect (c_window,&c_local_window_rect);
+#else
+ ValidRect (&c_local_window_rect);
+#endif
+ add_IO_time();
+ console_window_visible=1;
+ }
+}
+
+/*
+ #ifdef powerc
+ QDGlobals qd;
+ #endif
+**/
+
+#ifndef MACOSX
+
+#ifdef NO_INIT
+extern QDGlobals qd;
+#else
+QDGlobals qd;
+#endif
+
+#endif
+
+void w_print_char (char c)
+{
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+ window_print_char (c);
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+static void w_print_text_without_newlines (char *s,unsigned long length)
+{
+ unsigned long text_length,n;
+
+ text_length=TextWidth (s,0,length);
+ if (g_cur_x+text_length<c_window_width && cur_x+length<MAX_N_COLUMNS){
+ char *screen_char;
+ int n;
+
+ screen_char=&screen_chars[cur_y][cur_x];
+ for (n=0; n<length; ++n)
+ *screen_char++=s[n];
+ *screen_char=NEWLINE_CHAR;
+ DrawText (s,0,length);
+ g_cur_x+=text_length;
+ cur_x+=length;
+ } else
+ for (n=0; n<length; ++n)
+ window_print_char (s[n]);
+}
+
+void w_print_text (char *s,unsigned long length)
+{
+ char *end_s,c;
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+ end_s=s;
+ while (length!=0){
+ while (length!=0 && (c=*end_s,c!=NEWLINE_CHAR)){
+ ++end_s;
+ --length;
+ }
+ w_print_text_without_newlines (s,end_s-s);
+ if (length==0)
+ return;
+ print_newline();
+ --length;
+ s=++end_s;
+ }
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+static void e_print_newline()
+{
+ e_screen_chars[e_cur_y][e_cur_x]=NEWLINE_CHAR;
+ ++e_cur_y;
+ e_cur_x=0;
+ e_g_cur_x=0;
+ if (e_cur_y>=n_e_screen_lines){
+ e_cur_y=n_e_screen_lines-1;
+ scroll_window (e_window,e_screen_chars,n_e_screen_lines);
+ }
+#ifdef FLUSH_PORT_BUFFER
+ else
+ QDFlushPortBuffer (GetWindowPort (e_window),NULL);
+#endif
+ MoveTo (0,MULW(e_cur_y,char_height)+char_asc_lead);
+}
+
+static void e_print_char (char c)
+{
+ if (c==NEWLINE_CHAR)
+ e_print_newline();
+ else {
+ char *screen_char;
+ int w;
+
+ w=CharWidth (c);
+ if (e_g_cur_x+w>=e_window_width || e_cur_x+1>=MAX_N_COLUMNS)
+ e_print_newline();
+ e_g_cur_x+=w;
+
+ screen_char=&e_screen_chars[e_cur_y][e_cur_x];
+ *screen_char=c;
+ screen_char[1]=NEWLINE_CHAR;
+ DrawChar (c);
+ ++e_cur_x;
+ }
+}
+
+void ew_print_char (char c)
+{
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (e_window));
+#else
+ port=NULL;
+ if (qd.thePort!=e_window){
+ port=qd.thePort;
+ SetPort (e_window);
+ }
+#endif
+
+ if (!error_window_visible)
+ make_error_window_visible();
+
+ e_print_char (c);
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+static void e_print_text_without_newlines (char *s,unsigned long length)
+{
+ unsigned long text_length,n;
+
+ text_length=TextWidth (s,0,length);
+ if (e_g_cur_x+text_length<e_window_width && e_cur_x+length<MAX_N_COLUMNS){
+ char *screen_char;
+ int n;
+
+ screen_char=&e_screen_chars[e_cur_y][e_cur_x];
+ for (n=0; n<length; ++n)
+ *screen_char++=s[n];
+ *screen_char=NEWLINE_CHAR;
+ DrawText (s,0,length);
+ e_g_cur_x+=text_length;
+ e_cur_x+=length;
+ } else
+ for (n=0; n<length; ++n)
+ e_print_char (s[n]);
+}
+
+static void e_print_text (char *s,unsigned long length)
+{
+ char *end_s,c;
+
+ end_s=s;
+ while (length!=0){
+ while (length!=0 && (c=*end_s,c!=NEWLINE_CHAR)){
+ ++end_s;
+ --length;
+ }
+ e_print_text_without_newlines (s,end_s-s);
+ if (length==0)
+ return;
+ e_print_newline();
+ --length;
+ s=++end_s;
+ }
+}
+
+void ew_print_text (char *s,unsigned long length)
+{
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (e_window));
+#else
+ port=NULL;
+ if (qd.thePort!=e_window){
+ port=qd.thePort;
+ SetPort (e_window);
+ }
+#endif
+
+ if (!error_window_visible)
+ make_error_window_visible();
+
+ e_print_text (s,length);
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+static void w_show_cursor()
+{
+ int y;
+
+ y=MULW(cur_y,char_height);
+ MoveTo (g_cur_x,y+char_height);
+ LineTo (g_cur_x,y+1);
+ MoveTo (g_cur_x,y+char_asc_lead);
+}
+
+static void w_remove_cursor()
+{
+ PenMode (patBic);
+ w_show_cursor();
+ PenMode (patCopy);
+}
+
+static void w_remove_char (int w)
+{
+ Rect r;
+ int y;
+
+ y=MULW(cur_y,char_height);
+
+ r.bottom=y+char_height;
+ r.top=y+1;
+ r.left=g_cur_x;
+ r.right=g_cur_x+w-1;
+
+ EraseRect (&r);
+}
+
+void handle_update_or_mouse_down_event (EventRecord *event_p)
+{
+ if (event_p->what==updateEvt){
+ if ((WindowPtr)event_p->message==c_window){
+ w_remove_cursor();
+ update_window (c_window,screen_chars,n_screen_lines,g_cur_x,cur_y);
+ w_show_cursor();
+ } else if ((WindowPtr)event_p->message==e_window)
+ update_window (e_window,e_screen_chars,n_e_screen_lines,e_g_cur_x,e_cur_y);
+ } else if (event_p->what==mouseDown){
+ WindowPtr window;
+
+ if (FindWindow (event_p->where,&window)==inContent)
+ select_window (window);
+ }
+}
+
+static int w_read_char()
+{
+ add_execute_time();
+
+ while (1){
+#ifndef MACOSX
+ SystemTask();
+#endif
+ if (!GetNextEvent (everyEvent,&my_event))
+ continue;
+ switch (my_event.what){
+ case keyDown:
+ case autoKey:
+ {
+ int c;
+
+ c=my_event.message & 0xff;
+
+ add_IO_time();
+
+ return c;
+ }
+ case updateEvt:
+ case mouseDown:
+ handle_update_or_mouse_down_event (&my_event);
+ break;
+ }
+ }
+}
+
+static void w_read_line()
+{
+ int b_cur_x,b_cur_y,n_chars_read,c;
+
+ n_chars_read=0;
+ b_cur_x=cur_x;
+ b_cur_y=cur_y;
+
+ do {
+ w_show_cursor();
+ c=w_read_char();
+ w_remove_cursor();
+ if (c=='\b'){
+ if (n_chars_read>0){
+ while (cur_x==0){
+ int line_length,x,c;
+ char *screen_line;
+
+ --cur_y;
+ screen_line=screen_chars[cur_y];
+
+ line_length=0;
+ x=0;
+ while (c=screen_line[line_length],c!=NEWLINE_CHAR){
+ ++line_length;
+ x+=CharWidth (c);
+ }
+ cur_x=line_length;
+ g_cur_x=x;
+ }
+ if (cur_x>0){
+ int w;
+ char *screen_char;
+
+ --cur_x;
+ screen_char=&screen_chars[cur_y][cur_x];
+ w=CharWidth (*screen_char);
+ *screen_char=NEWLINE_CHAR;
+ g_cur_x-=w;
+ --n_chars_read;
+ w_remove_char (w);
+ }
+ }
+ } else {
+ if (c==NEWLINE_CHAR){
+ if (cur_y+1<n_screen_lines)
+ print_newline();
+ else
+ if (b_cur_y>0){
+ --b_cur_y;
+ print_newline();
+ }
+ } else {
+ char *screen_char;
+ int w;
+
+ w=CharWidth (c);
+ if (g_cur_x+w>=c_window_width || cur_x+1>=MAX_N_COLUMNS)
+ if (cur_y+1<n_screen_lines)
+ print_newline();
+ else
+ if (b_cur_y>0){
+ --b_cur_y;
+ print_newline();
+ } else
+ continue;
+ g_cur_x+=w;
+
+ screen_char=&screen_chars[cur_y][cur_x];
+ *screen_char=c;
+ screen_char[1]=NEWLINE_CHAR;
+ DrawChar (c);
+ ++cur_x;
+ ++n_chars_read;
+ }
+ }
+ } while (c!=NEWLINE_CHAR);
+
+ {
+ char *char_p,*screen_p;
+
+ input_buffer_length=n_chars_read+1;
+ input_buffer_pos=0;
+
+ char_p=input_buffer;
+ screen_p=&screen_chars[b_cur_y][b_cur_x];
+ while (n_chars_read!=0){
+ int c;
+
+ while (c=*screen_p++,c==NEWLINE_CHAR){
+ ++b_cur_y;
+ screen_p=screen_chars[b_cur_y];
+ }
+ *char_p++=c;
+ --n_chars_read;
+ }
+ *char_p++=NEWLINE_CHAR;
+ }
+}
+
+int w_get_char()
+{
+ int c;
+
+ if (input_buffer_length==0){
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+ w_read_line();
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+ }
+
+ c=input_buffer[input_buffer_pos] & 0xff;
+ ++input_buffer_pos;
+ --input_buffer_length;
+
+ return c;
+}
+
+#define is_digit(n) ((unsigned)((n)-'0')<(unsigned)10)
+
+int w_get_int (int *i_p)
+{
+ int c,negative;
+ unsigned int i;
+
+ c=w_get_char();
+ while (c==' ' || c=='\t' || c==NEWLINE_CHAR)
+ c=w_get_char();
+
+ negative=0;
+ if (c=='+')
+ c=w_get_char();
+ else
+ if (c=='-'){
+ c=w_get_char();
+ negative=1;
+ }
+
+ if (!is_digit (c)){
+ --input_buffer_pos;
+ ++input_buffer_length;
+
+ *i_p=0;
+ return 0;
+ }
+
+ i=c-'0';
+ while (c=w_get_char(),is_digit (c)){
+ i+=i<<2;
+ i+=i;
+ i+=c-'0';
+ };
+
+ if (negative)
+ i=-i;
+
+ --input_buffer_pos;
+ ++input_buffer_length;
+
+ *i_p=i;
+ return -1;
+}
+
+int w_get_real (double *r_p)
+{
+ char s[256+1];
+ int c,dot,digits,result,n;
+
+ n=0;
+
+ c=w_get_char();
+ while (c==' ' || c=='\t' || c==NEWLINE_CHAR)
+ c=w_get_char();
+
+ if (c=='+')
+ c=w_get_char();
+ else
+ if (c=='-'){
+ s[n++]=c;
+ c=w_get_char();
+ }
+
+ dot=0;
+ digits=0;
+
+ while (is_digit (c) || c=='.'){
+ if (c=='.'){
+ if (dot){
+ dot=2;
+ break;
+ }
+ dot=1;
+ } else
+ digits=-1;
+ if (n<256)
+ s[n++]=c;
+ c=w_get_char();
+ }
+
+ result=0;
+ if (digits)
+ if (dot==2 || ! (c=='e' || c=='E'))
+ result=-1;
+ else {
+ if (n<256)
+ s[n++]=c;
+ c=w_get_char();
+
+ if (c=='+')
+ c=w_get_char();
+ else
+ if (c=='-'){
+ if (n<256)
+ s[n++]=c;
+ c=w_get_char();
+ }
+
+ if (is_digit (c)){
+ do {
+ if (n<256)
+ s[n++]=c;
+ c=w_get_char();
+ } while (is_digit (c));
+
+ result=-1;
+ }
+ }
+
+ if (n>=256)
+ result=0;
+
+ --input_buffer_pos;
+ ++input_buffer_length;
+
+ *r_p=0.0;
+
+ if (result){
+ s[n]='\0';
+
+#if !defined (G_POWER)
+ result=convert_string_to_real (s,r_p);
+#else
+ if (sscanf (s,"%lg",r_p)!=1)
+ result=0;
+#endif
+ }
+
+ return result;
+}
+
+unsigned long w_get_text (char *string,unsigned long max_length)
+{
+ unsigned long length,l;
+ char *sp,*dp;
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+ if (input_buffer_length==0)
+ w_read_line();
+ length=input_buffer_length;
+ if (length>max_length)
+ length=max_length;
+
+ for (l=length,sp=&input_buffer[input_buffer_pos],dp=string; l!=0; --l)
+ *dp++=*sp++;
+
+ input_buffer_pos+=length;
+ input_buffer_length-=length;
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+
+ return length;
+}
+
+void w_print_string (char *s)
+{
+ char *end_s,c;
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+ end_s=s;
+ while (*s!='\0'){
+ while (c=*end_s,c!='\0' && c!=NEWLINE_CHAR)
+ ++end_s;
+ w_print_text_without_newlines (s,end_s-s);
+ if (*end_s=='\0')
+ break;
+ print_newline();
+ s=++end_s;
+ }
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+void ew_print_string (char *s)
+{
+ char *end_s,c;
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (e_window));
+#else
+ port=NULL;
+ if (qd.thePort!=e_window){
+ port=qd.thePort;
+ SetPort (e_window);
+ }
+#endif
+
+ if (!error_window_visible)
+ make_error_window_visible();
+
+ end_s=s;
+ while (*s!='\0'){
+ while (c=*end_s,c!='\0' && c!=NEWLINE_CHAR)
+ ++end_s;
+ e_print_text_without_newlines (s,end_s-s);
+ if (*end_s=='\0')
+ break;
+ e_print_newline();
+ s=++end_s;
+ }
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+#if !defined (G_POWER)
+extern char *convert_int_to_string (char *string,int i);
+extern char *convert_real_to_string (char *string,double *r_p);
+extern int convert_string_to_real (char *string,double *r_p);
+#endif
+
+void w_print_int (int n)
+{
+ char int_string [32];
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+#if !defined (G_POWER)
+ {
+ char *end_p;
+
+ end_p=convert_int_to_string (int_string,n);
+ w_print_text_without_newlines (int_string,end_p-int_string);
+ }
+#else
+ sprintf (int_string,"%d",n);
+ {
+ int string_length;
+ char *p;
+
+ string_length=0;
+ for (p=int_string; *p; ++p)
+ ++string_length;
+
+ w_print_text_without_newlines (int_string,string_length);
+ }
+#endif
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+void ew_print_int (int n)
+{
+ char int_string [32];
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (e_window));
+#else
+ port=NULL;
+ if (qd.thePort!=e_window){
+ port=qd.thePort;
+ SetPort (e_window);
+ }
+#endif
+
+ if (!error_window_visible)
+ make_error_window_visible();
+
+#if !defined (G_POWER)
+ {
+ char *end_p;
+
+ end_p=convert_int_to_string (int_string,n);
+ e_print_text_without_newlines (int_string,end_p-int_string);
+ }
+#else
+ sprintf (int_string,"%d",n);
+ {
+ int string_length;
+ char *p;
+
+ string_length=0;
+ for (p=int_string; *p; ++p)
+ ++string_length;
+
+ e_print_text_without_newlines (int_string,string_length);
+ }
+#endif
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+void w_print_real (double r)
+{
+ char real_string [40];
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (c_window));
+#else
+ port=NULL;
+ if (qd.thePort!=c_window){
+ port=qd.thePort;
+ SetPort (c_window);
+ }
+#endif
+
+ if (!console_window_visible)
+ make_console_window_visible();
+
+#if !defined (G_POWER)
+ {
+ char *end_p;
+
+ end_p=convert_real_to_string (real_string,&r);
+ w_print_text_without_newlines (real_string,end_p-real_string);
+ }
+#else
+ sprintf (real_string,"%.15g",r);
+ {
+ int string_length;
+ char *p;
+
+ string_length=0;
+ for (p=real_string; *p; ++p)
+ ++string_length;
+
+ w_print_text_without_newlines (real_string,string_length);
+ }
+#endif
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+void ew_print_real (double r)
+{
+ char real_string [40];
+ GrafPtr port;
+
+#ifdef MACOSX
+ GetPort (&port);
+ SetPort (GetWindowPort (e_window));
+#else
+ port=NULL;
+ if (qd.thePort!=e_window){
+ port=qd.thePort;
+ SetPort (e_window);
+ }
+#endif
+
+ if (!error_window_visible)
+ make_error_window_visible();
+
+#if !defined (G_POWER)
+ {
+ char *end_p;
+
+ end_p=convert_real_to_string (real_string,&r);
+ e_print_text_without_newlines (real_string,end_p-real_string);
+ }
+#else
+ sprintf (real_string,"%.15g",r);
+ {
+ int string_length;
+ char *p;
+
+ string_length=0;
+ for (p=real_string; *p; ++p)
+ ++string_length;
+
+ e_print_text_without_newlines (real_string,string_length);
+ }
+#endif
+
+#ifndef MACOSX
+ if (port!=NULL)
+#endif
+ SetPort (port);
+}
+
+static FontInfo font_info;
+static short font_id,font_size;
+
+long stack_size,heap_size,flags;
+#ifdef WRITE_HEAP
+long min_write_heap_size=0;
+#endif;
+#ifdef G_POWER
+long heap_size_multiple;
+long initial_heap_size;
+#endif
+
+static int init_terminal()
+{
+ int n;
+ int screen_top,screen_left,screen_bottom,screen_right;
+ int screen_width,screen_height,left_right_free,top_bottom_free;
+
+ int three,ten;
+
+#ifndef NO_INIT
+# ifndef MACOSX
+ InitGraf (&qd.thePort);
+ InitFonts();
+# endif
+ FlushEvents (everyEvent,0);
+# ifndef MACOSX
+ InitWindows();
+# endif
+ InitCursor();
+# ifndef MACOSX
+ InitMenus();
+# endif
+#endif
+
+ three=3; ten=10; /* to get a divw instead of a divl */
+
+#ifdef MACOSX
+ {
+ BitMap bit_map;
+
+ GetQDGlobalsScreenBits (&bit_map);
+
+ screen_top=bit_map.bounds.top;
+ screen_left=bit_map.bounds.left;
+ screen_bottom=bit_map.bounds.bottom;
+ screen_right=bit_map.bounds.right;
+ }
+#else
+ screen_top=qd.thePort->portRect.top;
+ screen_left=qd.thePort->portRect.left;
+ screen_bottom=qd.thePort->portRect.bottom;
+ screen_right=qd.thePort->portRect.right;
+#endif
+
+ screen_top+=15; /* menu bar height */
+
+ screen_width=screen_right-screen_left+1;
+ screen_height=screen_bottom-screen_top+1;
+
+ left_right_free=UDIVW (screen_width>>2,three); /* /12 */
+ top_bottom_free=12;
+
+ c_window_rect.left=screen_left+left_right_free;
+ c_window_rect.right=screen_right-left_right_free;
+
+ c_window_rect.top=screen_top+20+top_bottom_free;
+ c_window_rect.bottom=screen_top+UDIVW (screen_height*7,ten)-6;
+
+ c_local_window_rect.left=0;
+ c_local_window_rect.right=c_window_rect.right-c_window_rect.left;
+
+ c_local_window_rect.top=0;
+ c_local_window_rect.bottom=c_window_rect.bottom-c_window_rect.top;
+
+ e_window_rect.left=screen_left+left_right_free;
+ e_window_rect.right=screen_right-left_right_free;
+
+ e_window_rect.top=screen_top+20+UDIVW (screen_height*7,ten)+6;
+ e_window_rect.bottom=screen_bottom-top_bottom_free;
+
+ e_local_window_rect.left=0;
+ e_local_window_rect.right=e_window_rect.right-e_window_rect.left;
+
+ e_local_window_rect.top=0;
+ e_local_window_rect.bottom=e_window_rect.bottom-e_window_rect.top;
+
+ c_window_width=c_window_rect.right-c_window_rect.left+1;
+ c_window_height=c_window_rect.bottom-c_window_rect.top+1;
+
+ e_window_width=c_window_rect.right-e_window_rect.left+1;
+ e_window_height=e_window_rect.bottom-e_window_rect.top+1;
+
+ error_window_visible=0;
+
+ console_window_visible=flags & 16 ? 0 : 1;
+
+ c_window=NewWindow (NULL,&c_window_rect,"\pConsole",console_window_visible,0,(WindowPtr)-1,0,CONSOLE_WINDOW_ID);
+ if (c_window==NULL)
+ return 0;
+
+ e_window=NewWindow (NULL,&e_window_rect,"\pMessages",0,0,(WindowPtr)-1,0,ERROR_WINDOW_ID);
+ if (e_window==NULL)
+ return 0;
+
+#ifdef MACOSX
+ SetPort (GetWindowPort (e_window));
+#else
+ SetPort (e_window);
+#endif
+ TextFont (font_id);
+ TextSize (font_size);
+
+ GetFontInfo (&font_info);
+ char_ascent=font_info.ascent;
+ char_descent=font_info.descent;
+ char_leading=font_info.leading;
+ char_asc_lead=char_ascent+char_leading;
+ char_height=char_asc_lead+char_descent;
+
+ e_cur_y=0;
+ e_cur_x=0;
+ e_g_cur_x=0;
+ n_e_screen_lines=UDIVW (e_window_height,char_height);
+
+ MoveTo (0,char_asc_lead);
+
+#ifdef MACOSX
+ SetPort (GetWindowPort (c_window));
+#else
+ SetPort (c_window);
+#endif
+
+ TextFont (font_id);
+ TextSize (font_size);
+
+ cur_y=0;
+ cur_x=0;
+ g_cur_x=0;
+ n_screen_lines=UDIVW (c_window_height,char_height);
+
+ MoveTo (0,char_asc_lead);
+
+ if (console_window_visible){
+ SelectWindow (c_window);
+#ifdef MACOSX
+ ValidWindowRect (c_window,&c_local_window_rect);
+#else
+ ValidRect (&c_local_window_rect);
+#endif
+}
+
+ screen_chars=(SCREEN_LINE_CHARS*) NewPtr (n_screen_lines * (MAX_N_COLUMNS+1));
+ if (screen_chars==NULL)
+ return 0;
+
+ for (n=0; n<n_screen_lines; ++n)
+ screen_chars[n][0]=NEWLINE_CHAR;
+
+ e_screen_chars=(SCREEN_LINE_CHARS*) NewPtr (n_e_screen_lines * (MAX_N_COLUMNS+1));
+ if (e_screen_chars==NULL)
+ return 0;
+
+ for (n=0; n<n_e_screen_lines; ++n)
+ e_screen_chars[n][0]=NEWLINE_CHAR;
+
+ input_buffer=(char*) NewPtr (n_screen_lines * MAX_N_COLUMNS+1);
+ if (input_buffer==NULL)
+ return 0;
+
+ input_buffer_length=0;
+
+ return 1;
+}
+
+static void wait_key()
+{
+ while (1){
+#ifndef MACOSX
+ SystemTask();
+#endif
+ if (!GetNextEvent (everyEvent,&my_event))
+ continue;
+ switch (my_event.what){
+ case keyDown:
+ return;
+ case updateEvt:
+ case mouseDown:
+ handle_update_or_mouse_down_event (&my_event);
+ break;
+ }
+ }
+}
+
+#define VOID void
+
+void wait_for_key_press (VOID)
+{
+#if 1
+ SetWTitle (flags & 16 ? e_window : c_window,"\ppress any key to exit");
+#endif
+ wait_key();
+}
+
+static void exit_terminal()
+{
+ DisposeWindow (c_window);
+ DisposeWindow (e_window);
+/*
+ CloseWindow (c_window);
+ CloseWindow (e_window);
+*/
+}
+
+static void get_font_number (char *font_name)
+{
+ char system_font_name[256];
+
+ GetFNum ((unsigned char*)font_name,&font_id);
+
+ if (font_id==0){
+ char *s1,*s2;
+
+ GetFontName (0,(unsigned char*)system_font_name);
+
+ s1=system_font_name;
+ s2=font_name;
+ while (*s1==*s2 && *s1!='\0'){
+ ++s1;
+ ++s2;
+ }
+ if (*s1 || *s2)
+ font_id=-1;
+ }
+}
+
+#ifdef PARALLEL
+void load_code_segments (VOID)
+{
+ int n_code_resources,resource_number;
+
+ n_code_resources=Count1Resources ('CODE');
+
+ for (resource_number=1; resource_number<=n_code_resources; ++resource_number){
+ Handle resource;
+
+ SetResLoad (1);
+
+ resource=Get1Resource ('CODE',resource_number);
+ if (resource!=NULL && !ResError()){
+ MoveHHi (resource);
+ HLock (resource);
+ }
+ }
+}
+#endif
+
+#ifndef G_POWER
+ extern int target_processor;
+#endif
+
+#ifdef SIMULATE
+ extern int n_processors,processor_table_size;
+ extern int processor_table,end_processor_table;
+#endif
+
+SysEnvRec system_environment;
+int wait_next_event_available;
+
+#include <types.h>
+
+#ifndef powerc
+#pragma parameter __D0 MySysEnvirons (__D0, __A0)
+extern pascal OSErr MySysEnvirons(short versionRequested, SysEnvRec *theWorld)
+ ONEWORDINLINE(0xA090);
+#else
+#define MySysEnvirons SysEnvirons
+#endif
+
+#define MINIMUM_HEAP_SIZE_MULTIPLE ((2*256)+128)
+#define MAXIMUM_HEAP_SIZE_MULTIPLE (100*256)
+
+void (*exit_tcpip_function) (void);
+#ifndef MACHO
+extern void my_pointer_glue (void (*function) (void));
+#endif
+
+int execution_aborted;
+
+int main (void)
+{
+ Handle stack_handle,font_handle;
+#ifdef WRITE_HEAP
+ Handle profile_handle;
+#endif
+ long *stack_p;
+
+ exit_tcpip_function=NULL;
+ execution_aborted=0;
+
+#ifdef WRITE_HEAP
+ profile_handle=GetResource ('PRFL',128);
+ if (profile_handle!=NULL && *profile_handle!=NULL)
+ min_write_heap_size=**(long**)profile_handle;
+#endif
+
+#ifdef G_POWER
+ stack_handle=GetResource ('STHP',0);
+#else
+ stack_handle=GetResource ('STCK',0);
+#endif
+ stack_p=*(long**)stack_handle;
+
+ stack_size=(stack_p[0]+3) & ~3;
+ heap_size=(stack_p[2]+7) & ~7;
+ flags=stack_p[3];
+
+#ifdef SIMULATE
+ n_processors=stack_p[1];
+ if (n_processors<1)
+ n_processors=1;
+ if (n_processors>1024)
+ n_processors=1024;
+#else
+# ifdef G_POWER
+ heap_size_multiple=stack_p[1];
+ if (heap_size_multiple<MINIMUM_HEAP_SIZE_MULTIPLE)
+ heap_size_multiple=MINIMUM_HEAP_SIZE_MULTIPLE;
+ if (heap_size_multiple>MAXIMUM_HEAP_SIZE_MULTIPLE)
+ heap_size_multiple=MAXIMUM_HEAP_SIZE_MULTIPLE;
+ initial_heap_size=(stack_p[4]+7) & ~7;
+# endif
+#endif
+
+#ifndef MACOSX
+# ifndef PARALLEL
+ SetApplLimit (GetApplLimit()-stack_size-1024);
+# else
+ SetApplLimit (GetApplLimit()-heap_size-stack_size-1024);
+# endif
+ if (MemError()!=0)
+ return 0;
+#endif
+
+#ifdef PARALLEL
+ load_code_segments();
+#endif
+
+ font_id=-1;
+
+ font_handle=GetResource ('Font',128);
+ if (font_handle!=NULL){
+ get_font_number ((char*)((*(short **)font_handle)+1));
+ font_size=**(short**)font_handle;
+ }
+
+ if (font_id==-1){
+#ifdef NEW_HEADERS
+ font_id=kFontIDMonaco;
+#else
+ font_id=monaco;
+#endif
+ font_size=9;
+ }
+
+ if (!init_terminal())
+ return 1;
+
+/* srand (TickCount()); */
+
+#ifdef G_POWER
+ wait_next_event_available=1;
+#else
+# ifdef powerc
+ if (NGetTrapAddress (0xA860,ToolTrap)!=GetTrapAddress (0xA89F))
+# else
+ if (GetToolTrapAddress (0xA860)!=GetTrapAddress (0xA89F))
+# endif
+ wait_next_event_available=-1;
+ else
+ wait_next_event_available=0;
+#endif
+
+#ifndef MACOSX
+ if (MySysEnvirons (1,&system_environment)==noErr){
+# ifndef G_POWER
+ switch (target_processor){
+ case 2:
+ if (system_environment.processor==env68000 ||
+ system_environment.processor==env68010 ||
+ system_environment.hasFPU==0)
+ {
+ ew_print_string ("This program requires a MC68020 processor with MC68881 coprocessor or better\n");
+
+ wait_for_key_press();
+ exit_terminal();
+ return 0;
+ }
+ break;
+ case 1:
+ if (system_environment.processor==env68000 ||
+ system_environment.processor==env68010)
+ {
+ ew_print_string ("This program requires a MC68020 processor or better\n");
+
+ wait_for_key_press();
+ exit_terminal();
+ return 0;
+ }
+ }
+# endif
+ }
+#endif
+
+#ifdef SIMULATE
+ processor_table_size=n_processors*64;
+ processor_table=(int) NewPtr (processor_table_size);
+ end_processor_table=processor_table+processor_table_size;
+#endif
+
+#ifdef COMMUNICATION
+ if (init_communication())
+#endif
+
+ abc_main();
+
+#ifdef COMMUNICATION
+ exit_communication();
+#endif
+
+ if (exit_tcpip_function!=NULL)
+#ifdef MACHO
+ exit_tcpip_function();
+#else
+ my_pointer_glue (exit_tcpip_function);
+#endif
+
+ if (!(flags & 16) || (flags & 8) || execution_aborted!=0){
+#ifdef COMMUNICATION
+ if (my_processor_id==0)
+#endif
+ wait_for_key_press();
+ }
+ exit_terminal();
+
+#ifdef G_POWER
+ first_function();
+#endif
+
+ return 0;
+}
+
+#ifdef TIME_PROFILE
+void create_profile_file_name (unsigned char *profile_file_name)
+{
+ unsigned char *cur_ap_name,*end_profile_file_name;
+ int cur_ap_name_length,profile_file_name_length,n;
+
+ cur_ap_name=(unsigned char *)LMGetCurApName();
+ cur_ap_name_length=cur_ap_name[0];
+ ++cur_ap_name;
+
+ for (n=0; n<cur_ap_name_length; ++n)
+ profile_file_name[8+n]=cur_ap_name[n];
+
+ profile_file_name_length=cur_ap_name_length+13;
+ if (profile_file_name_length>31)
+ profile_file_name_length=31;
+
+ *((unsigned int*)&profile_file_name[4])=profile_file_name_length;
+
+ end_profile_file_name=&profile_file_name[8+profile_file_name_length];
+
+ end_profile_file_name[-13]=' ';
+ end_profile_file_name[-12]='T';
+ end_profile_file_name[-11]='i';
+ end_profile_file_name[-10]='m';
+ end_profile_file_name[-9]='e';
+ end_profile_file_name[-8]=' ';
+ end_profile_file_name[-7]='P';
+ end_profile_file_name[-6]='r';
+ end_profile_file_name[-5]='o';
+ end_profile_file_name[-4]='f';
+ end_profile_file_name[-3]='i';
+ end_profile_file_name[-2]='l';
+ end_profile_file_name[-1]='e';
+}
+#endif
+
+#if defined(G_POWER)
+static void my_user_item_proc (DialogPtr dialog_p,int the_item)
+{
+ short item_type;
+ Handle item_handle;
+ Rect item_rect;
+ PenState pen_state;
+
+ GetDialogItem (dialog_p,the_item,&item_type,&item_handle,&item_rect);
+
+ GetPenState (&pen_state);
+ PenNormal();
+ PenSize (3,3);
+ InsetRect (&item_rect,-4,-4);
+ FrameRoundRect (&item_rect,16,16);
+ SetPenState (&pen_state);
+}
+
+#if defined (MACOSX) && !defined (NEW_HEADERS)
+extern UserItemUPP NewUserItemUPP (ProcPtr);
+#endif
+
+#ifdef NEW_HEADERS
+int
+#else
+UserItemUPP
+#endif
+ myoutlinebuttonfunction (void)
+{
+#ifdef MACOSX
+ return NewUserItemUPP (my_user_item_proc);
+#else
+ return NewUserItemProc (my_user_item_proc);
+#endif
+}
+
+#ifndef NEW_HEADERS
+QDGlobals *qdglobals (void)
+{
+ return &qd;
+}
+#endif
+
+#endif
diff --git a/mcon.h b/mcon.h
new file mode 100644
index 0000000..1a17c38
--- /dev/null
+++ b/mcon.h
@@ -0,0 +1,16 @@
+extern int w_get_char();
+extern int w_get_int (int *i_p);
+extern int w_get_real (double *r_p);
+extern unsigned long w_get_text (char *string,unsigned long max_length);
+extern void w_print_char (char c);
+extern void w_print_int (int i);
+extern void w_print_real (double r);
+extern void w_print_string (char *s);
+extern void w_print_text (char *s,unsigned long length);
+extern void ew_print_char (char c);
+extern void ew_print_int (int i);
+extern void ew_print_real (double r);
+extern void ew_print_string (char *s);
+extern void ew_print_text (char *s,unsigned long length);
+extern void init_fileIO();
+extern void exit_fileIO();
diff --git a/mfileIO3.c b/mfileIO3.c
new file mode 100644
index 0000000..413469e
--- /dev/null
+++ b/mfileIO3.c
@@ -0,0 +1,2718 @@
+/*
+ File: mfileIO3.c
+ Written by: John van Groningen
+ At: University of Nijmegen
+*/
+
+#define MAC
+
+#if defined(powerc) || defined (MACHO)
+# define USE_CLIB 1
+#else
+# define USE_CLIB 0
+#endif
+
+#define NEWLINE_CHAR '\015'
+
+#include "mcon.h"
+
+extern void IO_error (char*);
+
+#ifndef MACHO
+# include <Traps.h>
+#endif
+#include <Memory.h>
+#include <Files.h>
+#include <Errors.h>
+#include <Script.h>
+
+#define EOF (-1)
+
+#define MAX_N_FILES 20
+
+#define MAX_FILE_NAME_LENGTH 255
+
+#define FIRST_REAL_FILE 4
+
+#define F_SEEK_SET 0
+#define F_SEEK_CUR 1
+#define F_SEEK_END 2
+
+#define pb_RefNum (((HIOParam*)&pb)->ioRefNum)
+#define pb_Permssn (((HIOParam*)&pb)->ioPermssn)
+#define pb_Misc (((HIOParam*)&pb)->ioMisc)
+#define pb_PosMode (((HIOParam*)&pb)->ioPosMode)
+#define pb_PosOffset (((HIOParam*)&pb)->ioPosOffset)
+#define pb_Buffer (((HIOParam*)&pb)->ioBuffer)
+#define pb_NamePtr (((HIOParam*)&pb)->ioNamePtr)
+#define pb_VRefNum (((HIOParam*)&pb)->ioVRefNum)
+#define pb_DirID (((HFileParam*)&pb)->ioDirID)
+#define pb_FDirIndex (((HFileParam*)&pb)->ioFDirIndex)
+#define pb_FlFndrInfo (((HFileParam*)&pb)->ioFlFndrInfo)
+#define pb_ReqCount (((HIOParam*)&pb)->ioReqCount)
+#define pb_ActCount (((HIOParam*)&pb)->ioActCount)
+
+struct file { /* 48 bytes */
+ unsigned char * file_read_p; /* offset 0 */
+ unsigned char * file_write_p; /* offset 4 */
+ unsigned char * file_end_buffer_p; /* offset 8 */
+ unsigned short file_mode; /* offset 12 */
+ char file_unique; /* offset 14 */
+ char file_error; /* offset 15 */
+
+ unsigned char * file_buffer_p;
+
+ unsigned long file_offset;
+ unsigned long file_length;
+
+ char * file_name;
+ long file_number;
+ unsigned long file_position;
+ unsigned long file_position_2;
+
+ short file_refnum;
+ short file_volume_number;
+};
+
+struct clean_string {
+ long length;
+#if (defined (powerc) && !defined (__MRC__)) || defined (MACHO)
+ char characters[0];
+#else
+ char characters[];
+#endif
+};
+
+#ifdef MAC
+#define allocate_memory NewPtr
+#define free_memory DisposePtr
+#else
+#define allocate_memory malloc
+#define free_memory free
+#endif
+
+static struct file file_table[MAX_N_FILES];
+
+static int number_of_files=FIRST_REAL_FILE;
+
+#define is_special_file(f) ((long)(f)<(long)(&file_table[3]))
+
+static char *clean_to_c_string (struct clean_string *cs)
+{
+ int l;
+ char *cp,*s;
+
+ cp=cs->characters;
+ l=cs->length;
+
+ s=allocate_memory (l+1);
+
+ if (s!=NULL){
+ register char *sp;
+
+ for (sp=s; l!=0; --l)
+ *sp++=*cp++;
+ *sp='\0';
+ }
+
+ return s;
+}
+
+static void copy_c_to_p_string (unsigned char *ps,char *cs,int max_length)
+{
+ unsigned char *p,*max_p;
+ char c;
+
+ p=ps+1;
+
+ max_p=p+max_length;
+
+ while ((c=*cs++)!=0){
+ if (p>=max_p){
+ *ps=0;
+ return;
+ }
+ *p++ = c;
+ }
+
+ *ps=p-(ps+1);
+}
+
+static int get_file_number (char *file_name,long *file_number_p)
+{
+ unsigned char file_name_s[MAX_FILE_NAME_LENGTH+1];
+ HFileParam fileParam;
+
+ copy_c_to_p_string (file_name_s,file_name,MAX_FILE_NAME_LENGTH);
+ if (file_name_s[0]==0)
+ return 0;
+
+ fileParam.ioFDirIndex=0;
+ fileParam.ioNamePtr=file_name_s;
+ fileParam.ioVRefNum=0;
+ fileParam.ioFDirIndex=-1;
+ fileParam.ioDirID=0;
+
+ if (PBHGetFInfoSync ((HParmBlkPtr)&fileParam)!=noErr)
+ return 0;
+
+ *file_number_p= fileParam.ioDirID;
+ return 1;
+}
+
+static int get_volume_number (char *file_name,short *volume_number_p)
+{
+ HVolumeParam volumeParam;
+ unsigned char file_name_s[MAX_FILE_NAME_LENGTH+1];
+
+ copy_c_to_p_string (file_name_s,file_name,MAX_FILE_NAME_LENGTH);
+ if (*file_name_s==0)
+ return 0;
+
+ volumeParam.ioVolIndex=-1;
+ volumeParam.ioNamePtr=file_name_s;
+ volumeParam.ioVRefNum=0;
+
+ if (PBHGetVInfoSync ((HParmBlkPtr)&volumeParam)!=noErr)
+ return 0;
+
+ *volume_number_p=volumeParam.ioVRefNum;
+ return 1;
+}
+
+static int file_exists (char *file_name,long *file_number_p,short *volume_number_p)
+{
+ int n;
+
+ *volume_number_p=0;
+
+ if (!get_file_number (file_name,file_number_p))
+ return -2;
+
+ if (!get_volume_number (file_name,volume_number_p))
+ IO_error ("can't determine volume number while opening file");
+
+ for (n=FIRST_REAL_FILE; n<number_of_files; ++n)
+ if (file_table[n].file_mode!=0 &&
+ file_table[n].file_number==*file_number_p &&
+ file_table[n].file_volume_number==*volume_number_p)
+ {
+ return n;
+ }
+
+ return -1;
+}
+
+#define FILE_IO_BUFFER_SIZE (4*1024)
+
+#define F_READ_TEXT 0
+#define F_WRITE_TEXT 1
+#define F_APPEND_TEXT 2
+#define F_READ_DATA 3
+#define F_WRITE_DATA 4
+#define F_APPEND_DATA 5
+
+#define ERROR_FILE ((struct file*)-(long)&file_table[2])
+
+static char file_permission[] ={ fsRdPerm,fsWrPerm,fsWrPerm,fsRdPerm,fsWrPerm,fsWrPerm };
+
+OSType new_file_creator='3PRM';
+
+struct file *open_file (struct clean_string *file_name,unsigned int file_mode)
+{
+ unsigned char p_file_name[MAX_FILE_NAME_LENGTH+1];
+ char *file_name_s;
+ int fn,existing_fn;
+ struct file *f;
+ long file_length;
+ long file_number;
+ unsigned char *buffer;
+ short file_refnum,volume_number;
+ OSErr error;
+ HParamBlockRec pb;
+ unsigned int buffer_mask;
+
+ buffer_mask = file_mode & ~255;
+ if (buffer_mask<8192)
+ buffer_mask=4095;
+ else if (buffer_mask>65535)
+ buffer_mask=65535;
+ else {
+ buffer_mask |= buffer_mask>>8;
+ buffer_mask |= buffer_mask>>4;
+ buffer_mask |= buffer_mask>>2;
+ buffer_mask |= buffer_mask>>1;
+ buffer_mask = (buffer_mask>>1) | 4095;
+ }
+
+ file_mode &= 255;
+
+ if (file_mode>5)
+ IO_error ("fopen: invalid file mode");
+
+ file_name_s=clean_to_c_string (file_name);
+ if (file_name_s==NULL){
+ IO_error ("fopen: out of memory");
+ return ERROR_FILE;
+ }
+
+ existing_fn=file_exists (file_name_s,&file_number,&volume_number);
+
+ if (existing_fn>=0){
+ free_memory (file_name_s);
+ return ERROR_FILE;
+/* IO_error ("fopen: file already open"); */
+ }
+
+ fn=number_of_files;
+ if (fn>=MAX_N_FILES){
+ for (fn=FIRST_REAL_FILE; fn<MAX_N_FILES; ++fn)
+ if (file_table[fn].file_mode==0)
+ break;
+
+ if (fn>=MAX_N_FILES){
+ free_memory (file_name_s);
+ IO_error ("fopen: too many files");
+ }
+ }
+
+ f=&file_table[fn];
+
+ f->file_number=file_number;
+ f->file_volume_number=volume_number;
+
+ copy_c_to_p_string (p_file_name,file_name_s,MAX_FILE_NAME_LENGTH);
+
+ if (existing_fn==-2 && ((1<<file_mode) & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)))){
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+
+ /* may be use HCreate, which also sets creator and filetype ? */
+
+ error=PBHCreateSync ((void*)&pb);
+ if (error!=noErr){
+ free_memory (file_name_s);
+ return ERROR_FILE;
+ }
+
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FDirIndex=0;
+
+ if (PBHGetFInfoSync ((void*)&pb)==noErr){
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FlFndrInfo.fdCreator=new_file_creator;
+ if ((1<<file_mode) & (1<<F_WRITE_TEXT))
+ pb_FlFndrInfo.fdType='TEXT';
+ PBHSetFInfoSync ((void*)&pb);
+ }
+ }
+
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_Misc=(Ptr)0;
+ pb_Permssn=file_permission[file_mode];
+
+ error=PBHOpenSync ((void*)&pb);
+ if (error!=noErr){
+ free_memory (file_name_s);
+ return ERROR_FILE;
+ }
+
+ file_refnum=pb_RefNum;
+
+ buffer=allocate_memory (buffer_mask+1);
+ if (buffer==NULL){
+ free_memory (file_name_s);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: out of memory");
+ }
+
+ f->file_buffer_p=buffer;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ f->file_offset=0;
+
+ switch (file_mode){
+ case F_WRITE_TEXT:
+ case F_WRITE_DATA:
+ pb_RefNum=file_refnum;
+ pb_Misc=(Ptr)0;
+
+ error=PBSetEOFSync ((ParmBlkPtr)&pb);
+
+ if (error!=noErr){
+ free_memory (file_name_s);
+ free_memory (buffer);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: can't set eof");
+ }
+
+ file_length=0;
+ break;
+ case F_APPEND_TEXT:
+ case F_APPEND_DATA:
+ pb_RefNum=file_refnum;
+ pb_PosMode=fsFromLEOF;
+ pb_PosOffset=0;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ if (error!=noErr){
+ free_memory (file_name_s);
+ free_memory (buffer);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: can't seek to eof");
+ }
+
+ file_length=pb_PosOffset;
+ f->file_offset=file_length;
+
+ break;
+ default:
+ pb_RefNum=file_refnum;
+
+ error=PBGetEOFSync ((ParmBlkPtr)&pb);
+
+ file_length=(long)pb_Misc;
+
+ if (error!=noErr){
+ free_memory (file_name_s);
+ free_memory (buffer);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: can't get eof");
+ }
+ }
+
+ f->file_mode=(1<<file_mode) | (buffer_mask & ~255);
+ f->file_unique=1;
+ f->file_error=0;
+
+ f->file_name=file_name_s;
+ f->file_length=file_length;
+ f->file_position=-2;
+ f->file_position_2=-1;
+ f->file_refnum=file_refnum;
+
+ if (fn>=number_of_files)
+ number_of_files=fn+1;
+
+ return f;
+}
+
+static int stdio_open=0;
+
+struct file *open_stdio (void)
+{
+ if (stdio_open)
+ IO_error ("stdio: already open");
+
+ stdio_open=1;
+ return &file_table[1];
+}
+
+static int open_stderr_file_failed=0;
+
+static int open_stderr_file (void)
+{
+ unsigned char p_file_name[MAX_FILE_NAME_LENGTH+1];
+ char *file_name_s;
+ int existing_fn;
+ struct file *f;
+ long file_length;
+ long file_number;
+ unsigned char *buffer;
+ short file_refnum,volume_number;
+ OSErr error;
+ unsigned int file_mode;
+ HParamBlockRec pb;
+
+ file_name_s="Messages";
+
+ file_mode=F_WRITE_TEXT;
+
+ if (!get_file_number (file_name_s,&file_number))
+ existing_fn=-2;
+ else {
+ if (!get_volume_number (file_name_s,&volume_number))
+ IO_error ("can't determine volume number while opening file");
+
+ existing_fn=-1;
+ }
+
+ f=&file_table[3];
+ f->file_number=file_number;
+ f->file_volume_number=volume_number;
+
+ copy_c_to_p_string (p_file_name,file_name_s,MAX_FILE_NAME_LENGTH);
+
+ if (existing_fn==-2){
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+
+ error=PBHCreateSync ((void*)&pb);
+ if (error!=noErr){
+ open_stderr_file_failed=1;
+ return 0;
+ }
+
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FDirIndex=0;
+
+ if (PBHGetFInfoSync ((void*)&pb)==noErr){
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FlFndrInfo.fdCreator=new_file_creator;
+ pb_FlFndrInfo.fdType='TEXT';
+ PBHSetFInfoSync ((void*)&pb);
+ }
+ }
+
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_Misc=(Ptr)0;
+ pb_Permssn=file_permission[file_mode];
+
+ error=PBHOpenSync ((void*)&pb);
+ if (error!=noErr){
+ open_stderr_file_failed=1;
+ return 0;
+ }
+
+ file_refnum=pb_RefNum;
+
+ buffer=allocate_memory (4096);
+ if (buffer==NULL){
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: out of memory");
+ }
+
+ f->file_buffer_p=buffer;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+ f->file_offset=0;
+
+ pb_RefNum=file_refnum;
+ pb_Misc=(Ptr)0;
+
+ error=PBSetEOFSync ((ParmBlkPtr)&pb);
+
+ if (error!=noErr){
+ free_memory (buffer);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("fopen: can't set eof");
+ }
+
+ file_length=0;
+
+ f->file_mode=(1<<file_mode);
+ f->file_unique=1;
+ f->file_error=0;
+
+ f->file_name=file_name_s;
+ f->file_length=file_length;
+ f->file_position=-2;
+ f->file_position_2=-1;
+ f->file_refnum=file_refnum;
+
+ return 1;
+}
+
+extern long flags;
+
+struct file *open_stderr (void)
+{
+ if ((flags & 128) && file_table[3].file_mode==0 && !open_stderr_file_failed)
+ open_stderr_file();
+
+ return file_table;
+}
+
+static int flush_write_buffer (struct file *f)
+{
+ if (f->file_mode & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)|(1<<F_APPEND_TEXT)|(1<<F_APPEND_DATA))){
+ unsigned char *buffer;
+
+ buffer=f->file_buffer_p;
+ if (buffer!=f->file_end_buffer_p){
+ OSErr error;
+ long count;
+
+ count=f->file_write_p-buffer;
+
+ if (count==0)
+ error=0;
+ else {
+ HParamBlockRec pb;
+
+ pb_RefNum=f->file_refnum;
+ pb_Buffer=buffer;
+ pb_ReqCount=count;
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+
+ count=pb_ActCount;
+
+ f->file_offset = pb_PosOffset;
+ }
+
+ if (f->file_offset > f->file_length)
+ f->file_length=f->file_offset;
+
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+
+ if (error!=noErr || count!=f->file_write_p-buffer){
+ f->file_write_p=buffer;
+ f->file_error=-1;
+ return 0;
+ }
+
+ f->file_write_p=buffer;
+ }
+ }
+
+ return 1;
+}
+
+int close_file (struct file *f)
+{
+ if (is_special_file (f)){
+ if (f==&file_table[1]){
+ if (!stdio_open)
+ IO_error ("fclose: file not open (stdio)");
+ stdio_open=0;
+ }
+ return -1;
+ } else {
+ HParamBlockRec pb;
+ int result;
+
+ if (f->file_mode==0)
+ IO_error ("fclose: file not open");
+
+ result=-1;
+
+ if (f->file_error)
+ result=0;
+
+ if (! flush_write_buffer (f))
+ result=0;
+
+ pb_RefNum=f->file_refnum;
+ if (PBCloseSync ((ParmBlkPtr)&pb)!=0)
+ result=0;
+
+ free_memory (f->file_name);
+ free_memory (f->file_buffer_p);
+
+ f->file_mode=0;
+
+ return result;
+ }
+}
+
+void close_stderr_file (void)
+{
+ if ((flags & 128) && file_table[3].file_mode!=0){
+ HParamBlockRec pb;
+ struct file *f;
+
+ f=&file_table[3];
+
+ flush_write_buffer (f);
+
+ pb_RefNum=f->file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+
+ free_memory (f->file_buffer_p);
+
+ f->file_mode=0;
+ }
+}
+
+int re_open_file (struct file *f,unsigned int file_mode)
+{
+ HParamBlockRec pb;
+ unsigned int buffer_mask;
+
+ buffer_mask = file_mode & ~255;
+ if (buffer_mask<8192)
+ buffer_mask=4095;
+ else if (buffer_mask>65535)
+ buffer_mask=65535;
+ else {
+ buffer_mask |= buffer_mask>>8;
+ buffer_mask |= buffer_mask>>4;
+ buffer_mask |= buffer_mask>>2;
+ buffer_mask |= buffer_mask>>1;
+ buffer_mask = (buffer_mask>>1) | 4095;
+ }
+
+ file_mode &= 255;
+
+ if (file_mode>5)
+ IO_error ("freopen: invalid file mode");
+
+ if (is_special_file (f)){
+ if (f==file_table && (file_mode==F_READ_TEXT || file_mode==F_READ_DATA))
+ IO_error ("freopen: stderr can't be opened for reading");
+ if (f==&file_table[2])
+ IO_error ("freopen: file not open");
+ return -1;
+ } else {
+ long file_length;
+ unsigned char p_file_name[MAX_FILE_NAME_LENGTH+1];
+ int result;
+ unsigned char *buffer;
+ short file_refnum;
+ OSErr error;
+
+ result=-1;
+
+ if (f->file_mode!=0){
+ flush_write_buffer (f);
+
+ pb_RefNum=f->file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+
+ if ((f->file_mode | 255)!=buffer_mask){
+ free_memory (f->file_buffer_p);
+
+ buffer=allocate_memory (buffer_mask+1);
+ if (buffer==NULL)
+ IO_error ("freopen: out of memory");
+ f->file_buffer_p=buffer;
+ }
+ } else {
+ buffer=allocate_memory (buffer_mask+1);
+ if (buffer==NULL)
+ IO_error ("freopen: out of memory");
+ f->file_buffer_p=buffer;
+ }
+
+ f->file_mode=0;
+
+ copy_c_to_p_string (p_file_name,f->file_name,MAX_FILE_NAME_LENGTH);
+
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_Misc=(Ptr)0;
+ pb_Permssn=file_permission[file_mode];
+
+ error=PBHOpenSync ((void*)&pb);
+ if (error!=noErr){
+ free_memory (f->file_name);
+ free_memory (f->file_buffer_p);
+ return 0;
+ }
+
+ file_refnum=pb_RefNum;
+
+ f->file_offset=0;
+
+ switch (file_mode){
+ case F_WRITE_TEXT:
+ case F_WRITE_DATA:
+ pb_RefNum=file_refnum;
+ pb_Misc=(Ptr)0;
+
+ error=PBSetEOFSync ((ParmBlkPtr)&pb);
+
+ if (error!=noErr){
+ free_memory (f->file_name);
+ free_memory (f->file_buffer_p);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("freopen: can't set eof");
+ }
+
+ file_length=0;
+ break;
+ case F_APPEND_TEXT:
+ case F_APPEND_DATA:
+ pb_RefNum=file_refnum;
+ pb_PosMode=fsFromLEOF;
+ pb_PosOffset=0;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ if (error!=noErr){
+ free_memory (f->file_name);
+ free_memory (f->file_buffer_p);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("freopen: can't seek to eof");
+ }
+
+ file_length=pb_PosOffset;
+ f->file_offset=file_length;
+ break;
+ default:
+ pb_RefNum=file_refnum;
+
+ error=PBGetEOFSync ((ParmBlkPtr)&pb);
+
+ file_length=(long)pb_Misc;
+
+ if (error!=noErr){
+ free_memory (f->file_name);
+ free_memory (f->file_buffer_p);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("freopen: can't get eof");
+ }
+ }
+
+ f->file_refnum=file_refnum;
+ f->file_mode= (1<<file_mode) | (buffer_mask & ~255);
+ f->file_length=file_length;
+ f->file_position=-2;
+ f->file_position_2=-1;
+ f->file_error=0;
+
+ buffer=f->file_buffer_p;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ return result;
+ }
+}
+
+static void char_to_new_buffer (int c,struct file *f)
+{
+ long count;
+ unsigned char *buffer;
+
+ flush_write_buffer (f);
+
+ count=((f->file_mode | 255)+1) - (f->file_offset & (f->file_mode | 255));
+ buffer=f->file_buffer_p;
+
+ *buffer=c;
+ f->file_write_p=buffer+1;
+ buffer+=count;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+}
+
+#if defined (__MWERKS__) || defined (powerc)
+#define write_char(c,f) if ((f)->file_write_p<(f)->file_end_buffer_p) \
+ *((f)->file_write_p)++=(c); \
+ else \
+ char_to_new_buffer((c),(f))
+#else
+#define write_char(c,f) ((f)->file_write_p<(f)->file_end_buffer_p ? (*((f)->file_write_p)++=(c)) : char_to_new_buffer((c),(f)))
+#endif
+
+static int char_from_new_buffer (struct file *f)
+{
+ OSErr error;
+ long count;
+ unsigned char *buffer;
+ HParamBlockRec pb;
+ int c;
+
+ count=((f->file_mode | 255)+1) - (f->file_offset & (f->file_mode | 255));
+ buffer=f->file_buffer_p;
+
+ pb_RefNum=f->file_refnum;
+ pb_Buffer=buffer;
+ pb_ReqCount=count;
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBReadSync ((ParmBlkPtr)&pb);
+ if (error==eofErr)
+ error=noErr;
+
+ count=pb_ActCount;
+
+ f->file_offset = pb_PosOffset;
+
+ if (error!=noErr)
+ f->file_error=-1;
+
+ if (error!=noErr || count==0){
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+ return EOF;
+ }
+
+ c=*buffer;
+ f->file_read_p=buffer+1;
+ buffer+=count;
+ f->file_end_buffer_p=buffer;
+ f->file_write_p=buffer;
+
+ return c;
+}
+
+#define read_char(f) ((f)->file_read_p<(f)->file_end_buffer_p ? *((f)->file_read_p)++ : char_from_new_buffer(f))
+
+int file_read_char (struct file *f)
+{
+ if (f->file_read_p < f->file_end_buffer_p)
+ return *(f->file_read_p)++;
+ else {
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("freadc: can't read from stderr");
+ else if (f==&file_table[1])
+ return w_get_char();
+ else
+ IO_error ("freadc: can't open this file");
+ } else {
+ if (! (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA))))
+ IO_error ("freadc: read from an output file");
+
+ return char_from_new_buffer (f);
+ }
+ }
+}
+
+#define is_digit(n) ((unsigned)((n)-'0')<(unsigned)10)
+
+int file_read_int (struct file *f,int *i_p)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("freadi: can't read from stderr");
+ else if (f==&file_table[1])
+ return w_get_int (i_p);
+ else
+ IO_error ("freadi: can't open this file");
+ } else {
+ *i_p=0;
+
+ if (f->file_mode & (1<<F_READ_DATA)){
+ int i;
+
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ return 0;
+ }
+ ((char*)i_p)[0]=i;
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ return 0;
+ }
+ ((char*)i_p)[1]=i;
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ return 0;
+ }
+ ((char*)i_p)[2]=i;
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ return 0;
+ }
+ ((char*)i_p)[3]=i;
+ } else if (f->file_mode & (1<<F_READ_TEXT)){
+ int c,negative,result;
+
+ result=-1;
+
+ while ((c=read_char (f))==' ' || c=='\t' || c=='\n' || c=='\r')
+ ;
+
+ negative=0;
+ if (c=='+')
+ c=read_char (f);
+ else
+ if (c=='-'){
+ c=read_char (f);
+ negative=1;
+ }
+
+ if (!is_digit (c)){
+ result=0;
+ f->file_error=-1;
+ } else {
+ unsigned int i;
+
+ i=c-'0';
+
+ while (is_digit (c=read_char (f))){
+ i+=i<<2;
+ i+=i;
+ i+=c-'0';
+ };
+
+ if (negative)
+ i=-i;
+
+ *i_p=i;
+ }
+
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+
+ return result;
+ } else
+ IO_error ("freadi: read from an output file");
+
+ return -1;
+ }
+}
+
+int file_read_real (struct file *f,double *r_p)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("freadr: can't read from stderr");
+ else if (f==&file_table[1])
+ return w_get_real (r_p);
+ else
+ IO_error ("freadr: can't open this file");
+ } else {
+ *r_p=0.0;
+
+ if (f->file_mode & (1<<F_READ_DATA)){
+ int n;
+
+ for (n=0; n<8; ++n){
+ int i;
+
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ return 0;
+ }
+ ((char*)r_p)[n]=i;
+ }
+ } else if (f->file_mode & (1<<F_READ_TEXT)){
+ int c,dot,digits,result,n;
+ char s[256+1];
+
+ n=0;
+
+ while ((c=read_char (f))==' ' || c=='\t' || c=='\n' || c=='\r')
+ ;
+
+ if (c=='+')
+ c=read_char (f);
+ else
+ if (c=='-'){
+ s[n++]=c;
+ c=read_char (f);
+ }
+
+ dot=0;
+ digits=0;
+
+ while (is_digit (c) || c=='.'){
+ if (c=='.'){
+ if (dot){
+ dot=2;
+ break;
+ }
+ dot=1;
+ } else
+ digits=-1;
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ }
+
+ result=0;
+ if (digits)
+ if (dot==2 || ! (c=='e' || c=='E'))
+ result=-1;
+ else {
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+
+ if (c=='+')
+ c=read_char (f);
+ else
+ if (c=='-'){
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ }
+
+ if (is_digit (c)){
+ do {
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ } while (is_digit (c));
+
+ result=-1;
+ }
+ }
+
+ if (n>=256)
+ result=0;
+
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+
+ *r_p=0.0;
+
+ if (result){
+ s[n]='\0';
+#if USE_CLIB
+ if (sscanf (s,"%lg",r_p)!=1)
+ result=0;
+ else
+ result=-1;
+#else
+ result=convert_string_to_real (s,r_p);
+#endif
+ }
+
+ if (!result)
+ f->file_error=-1;
+
+ return result;
+ } else
+ IO_error ("freadr: read from an output file");
+
+ return -1;
+ }
+}
+
+#define OLD_READ_STRING 0
+#define OLD_WRITE_STRING 0
+
+#if OLD_READ_STRING
+unsigned long file_read_string (struct file *f,unsigned long max_length,struct clean_string *s)
+{
+#else
+unsigned long file_read_characters (struct file *f,unsigned long *length_p,char *s)
+{
+ unsigned long max_length;
+
+ max_length=*length_p;
+#endif
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("freads: can't read from stderr");
+ else if (f==&file_table[1]){
+ char *string;
+ unsigned long length;
+
+ length=0;
+
+#if OLD_READ_STRING
+ string=s->characters;
+#else
+ string=s;
+#endif
+ while (length!=max_length){
+ *string++=w_get_char();
+ ++length;
+ }
+
+#if OLD_READ_STRING
+ s->length=length;
+#else
+ *length_p=length;
+#endif
+ return length;
+ } else
+ IO_error ("freads: can't open this file");
+ } else {
+ unsigned char *string,*end_string,*begin_string;
+
+ if (! (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA))))
+ IO_error ("freads: read from an output file");
+
+#if OLD_READ_STRING
+ string=s->characters;
+#else
+ string=s;
+#endif
+ begin_string=string;
+ end_string=string+max_length;
+
+ while (string<end_string){
+ if (f->file_read_p < f->file_end_buffer_p){
+ unsigned char *read_p;
+ long n;
+
+ read_p=f->file_read_p;
+
+ n=f->file_end_buffer_p-read_p;
+ if (n > end_string-string)
+ n=end_string-string;
+
+ do {
+ *string++ = *read_p++;
+ } while (--n);
+
+ f->file_read_p=read_p;
+ } else {
+ unsigned long align_buffer_mask;
+
+ /* (unsigned long) cast added to prevent apple mpw c compiler from generating incorrect code */
+ align_buffer_mask=~((unsigned long)f->file_mode | 255);
+
+ if ((f->file_offset+(end_string-string) & align_buffer_mask) != (f->file_offset & align_buffer_mask)){
+/* if (end_string-string>=FILE_IO_BUFFER_SIZE && (f->file_offset & (FILE_IO_BUFFER_SIZE-1))==0){ */
+ OSErr error;
+ long count;
+ unsigned char *buffer;
+ HParamBlockRec pb;
+
+ count=end_string-string;
+
+ if (f->file_offset+count < f->file_length)
+ count = (f->file_offset+count & align_buffer_mask) - f->file_offset;
+/* count &= ~(FILE_IO_BUFFER_SIZE-1); */
+
+ pb_RefNum=f->file_refnum;
+ pb_Buffer=string;
+ pb_ReqCount=count;
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBReadSync ((ParmBlkPtr)&pb);
+ if (error==eofErr)
+ error=noErr;
+
+ count=pb_ActCount;
+
+ f->file_offset = pb_PosOffset;
+
+ if (error!=noErr)
+ f->file_error=-1;
+
+ buffer=f->file_buffer_p;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ string+=count;
+
+ if (error!=noErr || count==0)
+#if OLD_READ_STRING
+ return (s->length=string-begin_string);
+#else
+ return (*length_p=string-begin_string);
+#endif
+ } else {
+ int c;
+
+ c=char_from_new_buffer (f);
+ if (c==EOF)
+ break;
+ *string++=c;
+ }
+ }
+ }
+
+#if OLD_READ_STRING
+ return (s->length=string-begin_string);
+#else
+ return (*length_p=string-begin_string);
+#endif
+ }
+}
+
+unsigned long file_read_line (struct file *f,unsigned long max_length,char *string)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("freadline: can't read from stderr");
+ else if (f==&file_table[1]){
+ unsigned long length;
+
+ length=0;
+
+ while (length!=max_length){
+ int c;
+
+ c=w_get_char();
+ *string++=c;
+ ++length;
+ if (c==NEWLINE_CHAR)
+ return length;
+ }
+
+ return -1;
+ } else
+ IO_error ("freadline: can't open this file");
+ } else {
+ unsigned char *end_string,*begin_string;
+ int c;
+
+ begin_string=string;
+ end_string=string+max_length;
+
+ c=0;
+
+ if (f->file_mode & (1<<F_READ_TEXT)){
+ while (string<end_string){
+ if (f->file_read_p < f->file_end_buffer_p){
+ unsigned char *read_p;
+ long n;
+
+ read_p=f->file_read_p;
+
+ n=f->file_end_buffer_p-read_p;
+ if (n > end_string-(unsigned char*)string)
+ n=end_string-(unsigned char*)string;
+
+ do {
+ char ch;
+
+ ch=*read_p++;
+ *string++=ch;
+ if (ch==NEWLINE_CHAR){
+ f->file_read_p=read_p;
+ return (unsigned char*)string-begin_string;
+ }
+ } while (--n);
+
+ c=0;
+ f->file_read_p=read_p;
+ } else {
+ c=char_from_new_buffer(f);
+ if (c==EOF)
+ break;
+
+ *string++=c;
+ if (c==NEWLINE_CHAR)
+ return (unsigned char*)string-begin_string;
+ }
+ }
+ } else if (f->file_mode & (1<<F_READ_DATA)){
+ while (string<end_string){
+ if (f->file_read_p < f->file_end_buffer_p){
+ unsigned char *read_p;
+ long n;
+
+ read_p=f->file_read_p;
+
+ n=f->file_end_buffer_p-read_p;
+ if (n > end_string-(unsigned char*)string)
+ n=end_string-(unsigned char*)string;
+ do {
+ char ch;
+
+ ch=*read_p++;
+
+ *string++=ch;
+ if (ch=='\xd'){
+ if (n>1){
+ if (*read_p=='\xa'){
+ *string++='\xa';
+ ++read_p;
+ }
+ f->file_read_p=read_p;
+ return (unsigned char*)string-begin_string;
+ } else if (read_p < f->file_end_buffer_p){
+ f->file_read_p=read_p;
+ if (*read_p!='\xa'){
+ return (unsigned char*)string-begin_string;
+ } else {
+ return -1; /* return \xd, read \xa next time */
+ }
+ } else {
+ int c;
+
+ f->file_read_p=read_p;
+ c=char_from_new_buffer(f);
+ read_p=f->file_read_p;
+
+ if (c!='\xa'){
+ if (read_p > f->file_buffer_p)
+ --read_p;
+
+ f->file_read_p=read_p;
+ return (unsigned char*)string-begin_string;
+ } else {
+ if (string<end_string){
+ *string++='\xa';
+ f->file_read_p=read_p;
+ return (unsigned char*)string-begin_string;
+ } else {
+ if (read_p > f->file_buffer_p)
+ --read_p;
+
+ f->file_read_p=read_p;
+ return -1; /* return \xd, read \xa next time */
+ }
+ }
+ }
+ } else if (ch=='\xa'){
+ f->file_read_p=read_p;
+ return (unsigned char*)string-begin_string;
+ }
+ } while (--n);
+
+ c=0;
+ f->file_read_p=read_p;
+ } else {
+ c=char_from_new_buffer(f);
+ if (c==EOF)
+ break;
+
+ *string++=c;
+
+ if (c=='\xd'){
+ c = read_char (f);
+ if (string<end_string){
+ if (c=='\xa')
+ *string++=c;
+ else
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+ } else {
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+
+ if (c=='\xa')
+ return -1;
+ }
+
+ return (unsigned char*)string-begin_string;
+ } else if (c=='\xa')
+ return (unsigned char*)string-begin_string;
+ }
+ }
+ } else
+ IO_error ("freadline: read from an output file");
+
+ if (c!=EOF)
+ return -1;
+
+ return (unsigned char*)string-begin_string;
+ }
+}
+
+void file_write_char (int c,struct file *f)
+{
+ if (f->file_write_p < f->file_end_buffer_p)
+ *(f->file_write_p)++=c;
+ else {
+ if (is_special_file (f)){
+ if (f==file_table){
+ ew_print_char (c);
+
+ if (!(flags & 128))
+ return;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+
+ if (f->file_write_p < f->file_end_buffer_p)
+ *(f->file_write_p)++=c;
+ else
+ char_to_new_buffer (c,f);
+
+ return;
+ } else if (f==&file_table[1]){
+ w_print_char (c);
+ return;
+ } else {
+ IO_error ("fwritec: can't open this file");
+ return;
+ }
+ }
+
+ if (! (f->file_mode & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)|(1<<F_APPEND_TEXT)|(1<<F_APPEND_DATA))))
+ IO_error ("fwritec: write to an input file");
+
+ char_to_new_buffer (c,f);
+ }
+}
+
+#if !USE_CLIB
+extern char *convert_int_to_string (char *string,int i);
+extern char *convert_real_to_string (char *string,double *r_p);
+#endif
+
+void file_write_int (int i,struct file *f)
+{
+ if (is_special_file (f)){
+ if (f==file_table){
+ ew_print_int (i);
+
+ if (!(flags & 128))
+ return;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+ } else if (f==&file_table[1]){
+ w_print_int (i);
+ return;
+ } else {
+ IO_error ("fwritei: can't open this file");
+ return;
+ }
+ }
+
+ if (! (f->file_mode & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)|(1<<F_APPEND_TEXT)|(1<<F_APPEND_DATA))))
+ IO_error ("fwritei: write to an input file");
+
+ if (f->file_mode & ((1<<F_WRITE_DATA)|(1<<F_APPEND_DATA))){
+#if defined (powerc)
+ /* work around bug in apple compiler for power macintosh */
+ write_char (i>>24,f);
+ write_char (i>>16,f);
+ write_char (i>>8,f);
+ write_char (i,f);
+#else
+ int v=i;
+
+ write_char (((char*)&v)[0],f);
+ write_char (((char*)&v)[1],f);
+ write_char (((char*)&v)[2],f);
+ write_char (((char*)&v)[3],f);
+#endif
+ } else {
+ unsigned char string[24],*end_p,*s;
+ int length;
+
+#if USE_CLIB
+ sprintf (string,"%d",i);
+ {
+ char *p;
+
+ length=0;
+ for (p=string; *p; ++p)
+ ++length;
+ }
+#else
+ end_p=convert_int_to_string (string,i);
+ length=end_p-string;
+#endif
+
+ s=string;
+ do {
+ write_char (*s++,f);
+ } while (--length);
+ }
+}
+
+void file_write_real (double r,struct file *f)
+{
+ if (is_special_file (f)){
+ if (f==file_table){
+ ew_print_real (r);
+
+ if (!(flags & 128))
+ return;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+ } else if (f==&file_table[1]){
+ w_print_real (r);
+ return;
+ } else {
+ IO_error ("fwriter: can't open this file");
+ return;
+ }
+ }
+
+ if (! (f->file_mode & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)|(1<<F_APPEND_TEXT)|(1<<F_APPEND_DATA))))
+ IO_error ("fwriter: write to an input file");
+
+ if (f->file_mode & ((1<<F_WRITE_DATA)|(1<<F_APPEND_DATA))){
+#ifdef powerc
+ /* work around bug in apple compiler for power macintosh */
+ int i1,i2;
+
+ i1=((int*)&r)[0];
+ i2=((int*)&r)[1];
+
+ write_char (i1>>24,f);
+ write_char (i1>>16,f);
+ write_char (i1>>8,f);
+ write_char (i1,f);
+ write_char (i2>>24,f);
+ write_char (i2>>16,f);
+ write_char (i2>>8,f);
+ write_char (i2,f);
+#else
+ double v=r;
+
+ write_char (((char*)&v)[0],f);
+ write_char (((char*)&v)[1],f);
+ write_char (((char*)&v)[2],f);
+ write_char (((char*)&v)[3],f);
+ write_char (((char*)&v)[4],f);
+ write_char (((char*)&v)[5],f);
+ write_char (((char*)&v)[6],f);
+ write_char (((char*)&v)[7],f);
+#endif
+ } else {
+ unsigned char string[32],*end_p,*s;
+ int length;
+
+#if USE_CLIB
+ sprintf (string,"%.15g",r);
+ {
+ char *p;
+
+ length=0;
+ for (p=string; *p; ++p)
+ ++length;
+ }
+#else
+ end_p=convert_real_to_string (string,&r);
+ length=end_p-string;
+#endif
+ s=string;
+ do {
+ write_char (*s++,f);
+ } while (--length);
+ }
+}
+
+#if OLD_WRITE_STRING
+void file_write_string (struct clean_string *s,struct file *f)
+#else
+void file_write_characters (unsigned char *p,int length,struct file *f)
+#endif
+{
+ if (is_special_file (f)){
+ if (f==file_table){
+#if OLD_WRITE_STRING
+ ew_print_text (s->characters,s->length);
+#else
+ ew_print_text (p,length);
+#endif
+ if (!(flags & 128))
+ return;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+ } else if (f==&file_table[1]){
+#if OLD_WRITE_STRING
+ w_print_text (s->characters,s->length);
+#else
+ w_print_text (p,length);
+#endif
+ return;
+ } else {
+ IO_error ("fwrites: can't open this file");
+ return;
+ }
+ }
+
+ {
+#if OLD_WRITE_STRING
+ unsigned char *p,*end_p;
+#else
+ unsigned char *end_p;
+#endif
+ if (! (f->file_mode & ((1<<F_WRITE_TEXT)|(1<<F_WRITE_DATA)|(1<<F_APPEND_TEXT)|(1<<F_APPEND_DATA))))
+ IO_error ("fwrites: write to an input file");
+
+#if OLD_WRITE_STRING
+ p=s->characters;
+ end_p=p+s->length;
+#else
+ end_p=p+length;
+#endif
+
+ while (p<end_p){
+ if (f->file_write_p < f->file_end_buffer_p){
+ unsigned char *write_p;
+ long n;
+
+ write_p=f->file_write_p;
+
+ n=f->file_end_buffer_p-write_p;
+ if (n>end_p-p)
+ n=end_p-p;
+
+ do {
+ *write_p++ = *p++;
+ } while (--n);
+
+ f->file_write_p=write_p;
+ } else
+ char_to_new_buffer (*p++,f);
+ }
+ }
+}
+
+int file_end (struct file *f)
+{
+ if (f->file_read_p < f->file_end_buffer_p)
+ return 0;
+
+ if (is_special_file (f)){
+ if (f==file_table || f==&file_table[1])
+ IO_error ("fend: not allowed for stdio and stderr");
+ else
+ IO_error ("fend: can't open file");
+ } else {
+ if (! (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA))))
+ IO_error ("fend: not allowed for output files");
+
+ if (f->file_offset < f->file_length)
+ return 0;
+
+ return -1;
+ }
+}
+
+int file_error (struct file *f)
+{
+ if (is_special_file (f)){
+ if (f==file_table || f==&file_table[1])
+ return 0;
+ else
+ return -1;
+ } else
+ return f->file_error;
+}
+
+unsigned long file_position (struct file *f)
+{
+ if (is_special_file (f)){
+ if (f==file_table || f==&file_table[1])
+ IO_error ("fposition: not allowed for stdio and stderr");
+ else
+ IO_error ("fposition: can't open file");
+ } else {
+ unsigned long position;
+
+ if (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA)))
+ position=f->file_offset - (f->file_end_buffer_p - f->file_read_p);
+ else
+ position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+
+ return position;
+ }
+}
+
+int file_seek (struct file *f,unsigned long position,unsigned long seek_mode)
+{
+ HParamBlockRec pb;
+
+ if (is_special_file (f)){
+ if (seek_mode>(unsigned)2)
+ IO_error ("fseek: invalid mode");
+
+ if (f==file_table || f==&file_table[1])
+ IO_error ("fseek: can't seek on stdio and stderr");
+ else
+ IO_error ("fseek: can't open file");
+ } else {
+ long current_position;
+ unsigned long buffer_size;
+
+ if (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA))){
+ current_position=f->file_offset - (f->file_end_buffer_p - f->file_read_p);
+
+ switch (seek_mode){
+ case F_SEEK_SET:
+ break;
+ case F_SEEK_CUR:
+ position+=current_position;
+ break;
+ case F_SEEK_END:
+ position=f->file_length-position;
+ break;
+ default:
+ IO_error ("fseek: invalid mode");
+ }
+
+ buffer_size=f->file_end_buffer_p - f->file_buffer_p;
+ if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){
+ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size));
+
+ return -1;
+ } else {
+ unsigned char *buffer;
+ OSErr error;
+
+ if (position<0 || position>f->file_length){
+ f->file_error=-1;
+ return 0;
+ }
+
+ buffer=f->file_buffer_p;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ pb_RefNum=f->file_refnum;
+ pb_PosMode=fsFromStart;
+ pb_PosOffset=position;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ f->file_offset=pb_PosOffset;
+
+ if (error!=noErr){
+ f->file_error=-1;
+ return 0;
+ }
+
+ return -1;
+ }
+ } else {
+ OSErr error;
+ int result;
+
+ result=-1;
+
+ current_position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+
+ if (current_position > f->file_length)
+ f->file_length=current_position;
+
+ switch (seek_mode){
+ case F_SEEK_SET:
+ break;
+ case F_SEEK_CUR:
+ position+=current_position;
+ break;
+ case F_SEEK_END:
+ position=f->file_length-position;
+ break;
+ default:
+ IO_error ("fseek: invalid mode");
+ }
+
+ if (position==current_position)
+ return -1;
+
+ if (! flush_write_buffer (f)){
+ f->file_error=-1;
+ result=0;
+ }
+
+ if (position<0 || position>f->file_length){
+ f->file_error=-1;
+ return 0;
+ }
+
+ pb_RefNum=f->file_refnum;
+ pb_PosMode=fsFromStart;
+ pb_PosOffset=position;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ f->file_offset=pb_PosOffset;
+
+ if (error!=noErr){
+ f->file_error=-1;
+ result=0;
+ }
+
+ return result;
+ }
+ }
+}
+
+struct file *open_s_file (struct clean_string *file_name,unsigned int file_mode)
+{
+ unsigned char p_file_name[MAX_FILE_NAME_LENGTH+1];
+ int fn,existing_fn;
+ char *file_name_s;
+ struct file *f;
+ long file_length;
+ long file_number;
+ short volume_number,file_refnum;
+ unsigned char *buffer;
+ OSErr error;
+ HParamBlockRec pb;
+ unsigned int buffer_mask;
+
+ buffer_mask = file_mode & ~255;
+ if (buffer_mask<8192)
+ buffer_mask=4095;
+ else if (buffer_mask>65535)
+ buffer_mask=65535;
+ else {
+ buffer_mask |= buffer_mask>>8;
+ buffer_mask |= buffer_mask>>4;
+ buffer_mask |= buffer_mask>>2;
+ buffer_mask |= buffer_mask>>1;
+ buffer_mask = (buffer_mask>>1) | 4095;
+ }
+
+ file_mode &= 255;
+
+ if (file_mode!=F_READ_TEXT && file_mode!=F_READ_DATA)
+ IO_error ("sfopen: invalid file mode");
+
+ file_name_s=clean_to_c_string (file_name);
+ if (file_name_s==NULL){
+ IO_error ("sfopen: out of memory");
+ return ERROR_FILE;
+ }
+
+ existing_fn=file_exists (file_name_s,&file_number,&volume_number);
+
+ if (existing_fn>=0){
+ if (file_table[existing_fn].file_unique)
+ IO_error ("sfopen: file already opened by fopen");
+
+ if ((file_table[existing_fn].file_mode & 255)!=(1<<file_mode))
+ IO_error ("sfopen: file already open in another file mode");
+
+ free_memory (file_name_s);
+
+ return &file_table[existing_fn];
+ }
+
+ fn=number_of_files;
+ if (fn>=MAX_N_FILES){
+ for (fn=FIRST_REAL_FILE; fn<MAX_N_FILES; ++fn)
+ if (file_table[fn].file_mode==0)
+ break;
+
+ if (fn>=MAX_N_FILES)
+ IO_error ("sfopen: too many files");
+ }
+ f=&file_table[fn];
+
+ f->file_number=file_number;
+ f->file_volume_number=volume_number;
+
+ copy_c_to_p_string (p_file_name,file_name_s,MAX_FILE_NAME_LENGTH);
+
+ pb_NamePtr=p_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_Misc=(Ptr)0;
+ pb_Permssn=file_permission[file_mode];
+
+ error=PBHOpenSync ((void*)&pb);
+ if (error!=noErr){
+ free_memory (file_name_s);
+ return ERROR_FILE;
+ }
+
+ file_refnum=pb_RefNum;
+
+ buffer=allocate_memory (buffer_mask+1);
+ if (buffer==NULL){
+ free_memory (file_name_s);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("sfopen: out of memory");
+ }
+
+ f->file_buffer_p=buffer;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ f->file_offset=0;
+
+ pb_RefNum=file_refnum;
+
+ error=PBGetEOFSync ((ParmBlkPtr)&pb);
+
+ file_length=(long)pb_Misc;
+
+ if (error!=noErr){
+ free_memory (file_name_s);
+ free_memory ((char*)buffer);
+ pb_RefNum=file_refnum;
+ PBCloseSync ((ParmBlkPtr)&pb);
+ IO_error ("sfopen: can't get eof");
+ }
+
+ f->file_refnum=file_refnum;
+ f->file_mode= (1<<file_mode) | (buffer_mask & ~255);
+ f->file_unique=0;
+ f->file_error=0;
+
+ f->file_name=file_name_s;
+ f->file_length=file_length;
+ f->file_position=-2;
+ f->file_position_2=-1;
+
+ if (fn>=number_of_files)
+ number_of_files=fn+1;
+
+ return f;
+}
+
+void file_share (struct file *f)
+{
+ f->file_unique=0;
+}
+
+static int simple_seek (struct file *f,long position)
+{
+ int result;
+ long buffer_size;
+ HParamBlockRec pb;
+
+ result=1;
+
+ buffer_size=f->file_end_buffer_p - f->file_buffer_p;
+ if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){
+ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size));
+ f->file_position=position;
+ } else {
+ unsigned char *buffer;
+ OSErr error;
+
+ if (position<0 || position>f->file_length){
+ f->file_error=-1;
+ result=0;
+ } else {
+ buffer=f->file_buffer_p;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ pb_RefNum=f->file_refnum;
+ pb_PosMode=fsFromStart;
+ pb_PosOffset=position;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ f->file_offset=pb_PosOffset;
+
+ if (error!=noErr){
+ f->file_error=-1;
+ result=0;
+ }
+ f->file_position=position;
+ }
+ }
+
+ return result;
+}
+
+int file_read_s_char (struct file *f,unsigned long *position_p)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("sfreadc: can't read from stderr");
+ else if (f==&file_table[1])
+ IO_error ("sfreadc: can't read from stdio, use freadc");
+ else
+ IO_error ("sfreadc: can't open this file");
+ } else {
+ int c;
+ unsigned long position;
+
+ position=*position_p;
+
+ if (f->file_position!=position){
+ if (f->file_unique)
+ IO_error ("sfreadc: can't read from a unique file");
+
+ switch (position){
+ case -1l:
+ if (position!=f->file_position_2)
+ position=f->file_position_2;
+ else {
+ position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+ f->file_position_2=position;
+ break;
+ }
+ default:
+ if (!simple_seek (f,position))
+ IO_error ("sfreadc: seek failed");
+ }
+ }
+
+ if (f->file_read_p < f->file_end_buffer_p){
+ c=*f->file_read_p++;
+ ++position;
+ } else {
+ c=char_from_new_buffer(f);
+ if (c!=EOF)
+ ++position;
+ }
+
+ f->file_position=position;
+ *position_p=position;
+
+ return c;
+ }
+}
+
+int file_read_s_int (struct file *f,int *i_p,unsigned long *position_p)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("sfreadi: can't read from stderr");
+ else if (f==&file_table[1])
+ IO_error ("sfreadi: can't read from stdio, use freadi");
+ else
+ IO_error ("sfreadi: can't open this file");
+ } else {
+ int result;
+ unsigned long position;
+
+ position=*position_p;
+
+ if (f->file_position!=position){
+ if (f->file_unique)
+ IO_error ("sfreadi: can't read from a unique file");
+
+ switch (position){
+ case -1l:
+ if (position!=f->file_position_2)
+ position=f->file_position_2;
+ else {
+ position=position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+ f->file_position_2=position;
+ break;
+ }
+ default:
+ if (!simple_seek (f,position))
+ IO_error ("sfreadi: seek failed");
+ }
+ }
+
+ *i_p=0;
+
+ result=-1;
+ if (f->file_mode & (1<<F_READ_DATA)){
+ int i;
+
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ result=0;
+ } else {
+ ((char*)i_p)[0]=i;
+ if ((i=read_char (f))==EOF){
+ ++position;
+ f->file_error=-1;
+ result=0;
+ } else {
+ ((char*)i_p)[1]=i;
+ if ((i=read_char (f))==EOF){
+ position+=2;
+ f->file_error=-1;
+ result=0;
+ } else {
+ ((char*)i_p)[2]=i;
+ if ((i=read_char (f))==EOF){
+ position+=3;
+ f->file_error=-1;
+ result=0;
+ } else {
+ ((char*)i_p)[3]=i;
+ position+=4;
+ }
+ }
+ }
+ }
+ } else if (f->file_mode & (1<<F_READ_TEXT)){
+ int c,negative,n_characters;
+
+ n_characters=-1;
+ ++n_characters;
+ while ((c=read_char (f))==' ' || c=='\t' || c=='\n' || c=='\r')
+ ++n_characters;
+
+ negative=0;
+ if (c=='+'){
+ c=read_char (f);
+ ++n_characters;
+ } else
+ if (c=='-'){
+ c=read_char (f);
+ ++n_characters;
+ negative=1;
+ }
+
+ if (!is_digit (c)){
+ f->file_error=-1;
+ result=0;
+ } else {
+ unsigned int i;
+
+ i=c-'0';
+
+ ++n_characters;
+ while (is_digit (c=read_char (f))){
+ i+=i<<2;
+ i+=i;
+ i+=c-'0';
+ ++n_characters;
+ };
+
+ if (negative)
+ i=-i;
+
+ *i_p=i;
+ }
+
+ position+=n_characters;
+
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+ }
+
+ f->file_position=position;
+ *position_p=position;
+
+ return result;
+ }
+}
+
+int file_read_s_real (struct file *f,double *r_p,unsigned long *position_p)
+{
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("sfreadr: can't read from stderr");
+ else if (f==&file_table[1])
+ IO_error ("sfreadr: can't read from stdio, use freadr");
+ else
+ IO_error ("sfreadr: can't open this file");
+ } else {
+ int result;
+ unsigned long position;
+
+ position=*position_p;
+ if (f->file_position!=position){
+ if (f->file_unique)
+ IO_error ("sfreadr: can't read from a unique file");
+
+ switch (position){
+ case -1l:
+ if (position!=f->file_position_2)
+ position=f->file_position_2;
+ else {
+ position=position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+ f->file_position_2=position;
+ break;
+ }
+ default:
+ if (!simple_seek (f,position))
+ IO_error ("sfreadr: seek failed");
+ }
+ }
+
+ *r_p=0.0;
+
+ if (f->file_mode & (1<<F_READ_DATA)){
+ int n;
+
+ result=-1;
+ for (n=0; n<8; ++n){
+ int i;
+
+ if ((i=read_char (f))==EOF){
+ f->file_error=-1;
+ result=0;
+ break;
+ }
+ ((char*)r_p)[n]=i;
+ }
+
+ position+=n;
+ } else if (f->file_mode & (1<<F_READ_TEXT)){
+ int c,dot,digits,result,n,n_characters;
+ char s[256+1];
+
+ n_characters=-1;
+
+ n=0;
+
+ ++n_characters;
+ while ((c=read_char (f))==' ' || c=='\t' || c=='\n' || c=='\r')
+ ++n_characters;
+
+ if (c=='+'){
+ c=read_char (f);
+ ++n_characters;
+ } else
+ if (c=='-'){
+ s[n++]=c;
+ c=read_char (f);
+ ++n_characters;
+ }
+
+ dot=0;
+ digits=0;
+
+ while (is_digit (c) || c=='.'){
+ if (c=='.'){
+ if (dot){
+ dot=2;
+ break;
+ }
+ dot=1;
+ } else
+ digits=-1;
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ ++n_characters;
+ }
+
+ result=0;
+ if (digits)
+ if (dot==2 || ! (c=='e' || c=='E'))
+ result=-1;
+ else {
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ ++n_characters;
+
+ if (c=='+'){
+ c=read_char (f);
+ ++n_characters;
+ } else
+ if (c=='-'){
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ ++n_characters;
+ }
+
+ if (is_digit (c)){
+ do {
+ if (n<256)
+ s[n++]=c;
+ c=read_char (f);
+ ++n_characters;
+ } while (is_digit (c));
+
+ result=-1;
+ }
+ }
+
+ if (n>=256)
+ result=0;
+
+ position+=n_characters;
+
+ if (f->file_read_p > f->file_buffer_p)
+ --f->file_read_p;
+
+ *r_p=0.0;
+
+ if (result){
+ s[n]='\0';
+#if USE_CLIB
+ if (sscanf (s,"%lg",r_p)!=1)
+ result=0;
+ else
+ result=-1;
+#else
+ result=convert_string_to_real (s,r_p);
+#endif
+ }
+
+ if (!result)
+ f->file_error=-1;
+ }
+
+ f->file_position=position;
+ *position_p=position;
+
+ return result;
+ }
+}
+
+unsigned long file_read_s_string
+ (struct file *f,unsigned long max_length,struct clean_string *s,unsigned long *position_p)
+{
+ unsigned long length;
+
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("sfreads: can't read from stderr");
+ else if (f==&file_table[1])
+ IO_error ("sfreads: can't read from stdio, use freads");
+ else
+ IO_error ("sfreads: can't open this file");
+ } else {
+ unsigned long position;
+ char *string;
+ int c;
+
+ position=*position_p;
+ if (f->file_position!=position){
+ if (f->file_unique)
+ IO_error ("sfreads: can't read from a unique file");
+
+ switch (position){
+ case -1l:
+ if (position!=f->file_position_2)
+ position=f->file_position_2;
+ else {
+ position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+ f->file_position_2=position;
+ break;
+ }
+ default:
+ if (!simple_seek (f,position))
+ IO_error ("sfreads: seek failed");
+ }
+ }
+
+ length=0;
+ string=s->characters;
+
+ while (length!=max_length && ((c=read_char (f))!=EOF)){
+ *string++=c;
+ ++length;
+ }
+
+ s->length=length;
+
+ position+=length;
+
+ f->file_position=position;
+ *position_p=position;
+
+ return length;
+ }
+}
+
+unsigned long file_read_s_line
+ (struct file *f,unsigned long max_length,char *string,unsigned long *position_p)
+{
+ unsigned long length;
+
+ if (is_special_file (f)){
+ if (f==file_table)
+ IO_error ("sfreadline: can't read from stderr");
+ else if (f==&file_table[1])
+ IO_error ("sfreadline: can't read from stdio, use freadline");
+ else
+ IO_error ("sfreadline: can't open this file");
+ } else {
+ unsigned long position;
+ int c;
+
+ position=*position_p;
+ if (f->file_position!=position){
+ if (f->file_unique)
+ IO_error ("sfreadline: can't read from a unique file");
+
+ if (! (f->file_mode & (1<<F_READ_TEXT)))
+ IO_error ("sfreadline: read from a data file");
+
+ switch (position){
+ case -1l:
+ if (position!=f->file_position_2)
+ position=f->file_position_2;
+ else {
+ position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+ f->file_position_2=position;
+ break;
+ }
+ default:
+ if (!simple_seek (f,position))
+ IO_error ("sfreadline: seek failed");
+ }
+ }
+
+ length=0;
+
+ c=0;
+ while (length!=max_length && ((c=read_char (f))!=EOF)){
+ *string++=c;
+ ++length;
+ if (c==NEWLINE_CHAR)
+ break;
+ }
+
+ position+=length;
+
+ f->file_position=position;
+ *position_p=position;
+
+ if (c!=NEWLINE_CHAR && c!=EOF)
+ return -1;
+
+ return length;
+ }
+}
+
+int file_s_end (struct file *f,unsigned long position)
+{
+ if (is_special_file (f)){
+ if (f==file_table || f==&file_table[1])
+ IO_error ("sfend: not allowed for stdio and stderr");
+ else
+ IO_error ("sfend: can't open file");
+ } else {
+ if (f->file_unique){
+ if (! (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA))))
+ IO_error ("sfend: not allowed for output files");
+
+ if (f->file_read_p < f->file_end_buffer_p)
+ return 0;
+
+ if (f->file_offset < f->file_length)
+ return 0;
+
+ return -1;
+ } else {
+ if (position==-1l){
+ if (f->file_position_2!=-1l)
+ position=f->file_position_2;
+ else {
+ position=f->file_offset + (f->file_end_buffer_p - f->file_read_p);
+ f->file_position=position;
+ f->file_position_2=position;
+ }
+ }
+
+ return (position==f->file_length) ? -1 : 0;
+ }
+ }
+}
+
+unsigned long file_s_position (struct file *f,unsigned long position)
+{
+ if (is_special_file (f)){
+ if (f==file_table || f==&file_table[1])
+ IO_error ("sfposition: not allowed for stdio and stderr");
+ else
+ IO_error ("sfposition: can't open file");
+ } else {
+ if (f->file_unique){
+ if (f->file_mode & ((1<<F_READ_TEXT) | (1<<F_READ_DATA)))
+ position=f->file_offset - (f->file_end_buffer_p - f->file_read_p);
+ else
+ position=f->file_offset + (f->file_write_p - f->file_buffer_p);
+
+ return position;
+ } else {
+ if (position==-1l){
+ if (f->file_position_2!=-1l)
+ return f->file_position_2;
+ else {
+ position=f->file_offset - (f->file_end_buffer_p - f->file_read_p);
+
+ f->file_position=position;
+ f->file_position_2=position;
+ }
+ }
+
+ return position;
+ }
+ }
+}
+
+#define F_SEEK_SET 0
+#define F_SEEK_CUR 1
+#define F_SEEK_END 2
+
+int file_s_seek (struct file *f,unsigned long position,unsigned long seek_mode,unsigned long *position_p)
+{
+ HParamBlockRec pb;
+
+ if (is_special_file (f)){
+ if (seek_mode>(unsigned)2)
+ IO_error ("sfseek: invalid mode");
+
+ if (f==file_table)
+ IO_error ("sfseek: can't seek on stdio");
+ else if (f==&file_table[1])
+ IO_error ("sfseek: can't seek on stderr");
+ else
+ IO_error ("sfseek: can't open file");
+ } else {
+ long current_position,buffer_size;
+ int result;
+
+ result=-1;
+
+ if (f->file_unique)
+ IO_error ("sfseek: can't seek on a unique file");
+
+ current_position=f->file_offset - (f->file_end_buffer_p - f->file_read_p);
+
+ if (*position_p==-1l){
+ if (f->file_position_2!=-1l)
+ *position_p=f->file_position_2;
+ else {
+ f->file_position_2=current_position;
+ *position_p=current_position;
+ }
+ }
+
+ switch (seek_mode){
+ case F_SEEK_SET:
+ break;
+ case F_SEEK_CUR:
+ position+=*position_p;
+ break;
+ case F_SEEK_END:
+ position=f->file_length+position;
+ break;
+ default:
+ IO_error ("sfseek: invalid mode");
+ }
+
+ buffer_size=f->file_end_buffer_p - f->file_buffer_p;
+ if ((unsigned long)(position - (f->file_offset-buffer_size)) < buffer_size){
+ f->file_read_p = f->file_buffer_p + (position - (f->file_offset-buffer_size));
+ f->file_position=position;
+ } else {
+ unsigned char *buffer;
+ OSErr error;
+
+ if (position<0 || position>f->file_length){
+ f->file_error=-1;
+ result=0;
+ f->file_position=current_position;
+ } else {
+ buffer=f->file_buffer_p;
+ f->file_end_buffer_p=buffer;
+ f->file_read_p=buffer;
+ f->file_write_p=buffer;
+
+ pb_RefNum=f->file_refnum;
+ pb_PosMode=fsFromStart;
+ pb_PosOffset=position;
+
+ error=PBSetFPosSync ((ParmBlkPtr)&pb);
+
+ f->file_offset=pb_PosOffset;
+
+ if (error!=noErr){
+ f->file_error=-1;
+ result=0;
+ }
+
+ f->file_position=position;
+ }
+ }
+
+ *position_p=position;
+
+ return result;
+ }
+}
+
+void er_print_char (char c)
+{
+ ew_print_char (c);
+
+ if (flags & 128){
+ struct file *f;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+
+ if (f->file_write_p < f->file_end_buffer_p)
+ *(f->file_write_p)++=c;
+ else
+ char_to_new_buffer (c,f);
+ }
+}
+
+void er_print_int (int i)
+{
+ ew_print_int (i);
+
+ if (flags & 128){
+ if (file_table[3].file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+
+ file_write_int (i,&file_table[3]);
+ }
+}
+
+static void write_chars (unsigned char *p,unsigned char *end_p,struct file *f)
+{
+ while (p<end_p){
+ if (f->file_write_p < f->file_end_buffer_p){
+ unsigned char *write_p;
+ long n;
+
+ write_p=f->file_write_p;
+
+ n=f->file_end_buffer_p-write_p;
+ if (n>end_p-p)
+ n=end_p-p;
+
+ do {
+ *write_p++ = *p++;
+ } while (--n);
+
+ f->file_write_p=write_p;
+ } else
+ char_to_new_buffer (*p++,f);
+ }
+}
+
+void er_print_text (char *s,unsigned long length)
+{
+ ew_print_text (s,length);
+
+ if (flags & 128){
+ struct file *f;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+
+ write_chars (s,s+length,f);
+ }
+}
+
+void er_print_string (char *s)
+{
+ ew_print_string (s);
+
+ if (flags & 128){
+ unsigned char *end_p;
+ struct file *f;
+
+ f=&file_table[3];
+ if (f->file_mode==0){
+ if (open_stderr_file_failed || !open_stderr_file())
+ return;
+ }
+
+ end_p=s;
+ while (*end_p)
+ ++end_p;
+
+ write_chars (s,end_p,f);
+ }
+}
diff --git a/mwrite_heap.c b/mwrite_heap.c
new file mode 100644
index 0000000..ce2f2c3
--- /dev/null
+++ b/mwrite_heap.c
@@ -0,0 +1,237 @@
+
+#include <Traps.h>
+#include <Memory.h>
+#include <Files.h>
+#include <Errors.h>
+#include <Script.h>
+#include <Resources.h>
+#include <LowMem.h>
+
+#define pb_RefNum (((HIOParam*)&pb)->ioRefNum)
+#define pb_Permssn (((HIOParam*)&pb)->ioPermssn)
+#define pb_Misc (((HIOParam*)&pb)->ioMisc)
+#define pb_PosMode (((HIOParam*)&pb)->ioPosMode)
+#define pb_PosOffset (((HIOParam*)&pb)->ioPosOffset)
+#define pb_Buffer (((HIOParam*)&pb)->ioBuffer)
+#define pb_NamePtr (((HIOParam*)&pb)->ioNamePtr)
+#define pb_VRefNum (((HIOParam*)&pb)->ioVRefNum)
+#define pb_DirID (((HFileParam*)&pb)->ioDirID)
+#define pb_FDirIndex (((HFileParam*)&pb)->ioFDirIndex)
+#define pb_FlFndrInfo (((HFileParam*)&pb)->ioFlFndrInfo)
+#define pb_ReqCount (((HIOParam*)&pb)->ioReqCount)
+#define pb_ActCount (((HIOParam*)&pb)->ioActCount)
+
+struct heap_info {
+ int *heap1_begin;
+ int *heap1_end;
+ int *heap2_begin;
+ int *heap2_end;
+ int *stack_begin;
+ int *stack_end;
+ int *text_begin;
+ int *data_begin;
+ int *small_integers;
+ int *characters;
+ int int_descriptor;
+ int char_descriptor;
+ int real_descriptor;
+ int bool_descriptor;
+ int string_descriptor;
+ int array_descriptor;
+};
+
+static int heap_written_count=0;
+
+#define MAX_N_HEAPS 10
+
+void write_heap (struct heap_info *h)
+{
+ HParamBlockRec pb;
+ OSErr error;
+ Str32 application_name,heap_file_name;
+ int application_name_length;
+
+ if (heap_written_count>=MAX_N_HEAPS)
+ return;
+
+ {
+ unsigned char *s;
+ int n;
+
+ s=LMGetCurApName();
+ application_name_length=*s++;
+
+ for (n=0; n<32; ++n){
+ if (n>=application_name_length)
+ application_name[n]='\0';
+ else {
+ application_name[n]=*s;
+ if (*s!='\0')
+ ++s;
+ }
+ }
+ }
+
+ {
+ char *end_heap_file_name_p;
+ int n,heap_file_name_length;
+
+ for (n=0; n<application_name_length; ++n)
+ heap_file_name[1+n]=application_name[n];
+
+ heap_file_name_length=application_name_length+14;
+ if (heap_file_name_length>31)
+ heap_file_name_length=31;
+ heap_file_name[0]=heap_file_name_length;
+
+ end_heap_file_name_p=(char*)&heap_file_name[1+heap_file_name_length];
+
+ end_heap_file_name_p[-14]=' ';
+ end_heap_file_name_p[-13]='H';
+ end_heap_file_name_p[-12]='e';
+ end_heap_file_name_p[-11]='a';
+ end_heap_file_name_p[-10]='p';
+ end_heap_file_name_p[-9]=' ';
+ end_heap_file_name_p[-8]='P';
+ end_heap_file_name_p[-7]='r';
+ end_heap_file_name_p[-6]='o';
+ end_heap_file_name_p[-5]='f';
+ end_heap_file_name_p[-4]='i';
+ end_heap_file_name_p[-3]='l';
+ end_heap_file_name_p[-2]='e';
+ end_heap_file_name_p[-1]='0'+heap_written_count++;
+ }
+
+ pb_NamePtr=heap_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+
+ error=PBHCreateSync ((void*)&pb);
+ if (error!=noErr && error!=-48/* dupFNErr*/){
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FDirIndex=0;
+
+ if (PBHGetFInfoSync ((void*)&pb)==noErr){
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_FlFndrInfo.fdCreator='PRHP';
+ pb_FlFndrInfo.fdType='PRHP';
+ PBHSetFInfoSync ((void*)&pb);
+ }
+
+ pb_NamePtr=heap_file_name;
+ pb_VRefNum=0;
+ pb_DirID=0;
+ pb_Misc=(Ptr)0;
+ pb_Permssn=fsWrPerm;
+
+ error=PBHOpenSync ((void*)&pb);
+ if (error!=noErr){
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ pb_Buffer=(char*)application_name;
+ pb_ReqCount=32;
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ pb_Buffer=(char*)h;
+ pb_ReqCount=sizeof (struct heap_info);
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+#if 0
+ {
+ int n;
+ Handle h;
+
+ n=0;
+ do {
+ h=Get1Resource ('CODE',n);
+
+ if (h!=NULL)
+ pb_Buffer=(char*)h;
+ else
+ pb_Buffer=(char*)&h;
+ pb_ReqCount=sizeof (Ptr);
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ ++n;
+ } while (h!=NULL);
+ }
+#endif
+
+ pb_Buffer=(char*)h->stack_begin;
+ pb_ReqCount=(int)(h->stack_end) - (int)(h->stack_begin);
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ pb_Buffer=(char*)h->heap1_begin;
+ pb_ReqCount=(int)(h->heap1_end) - (int)(h->heap1_begin);
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+
+ if (h->heap2_begin!=h->heap2_end){
+ pb_Buffer=(char*)h->heap2_begin;
+ pb_ReqCount=(int)(h->heap2_end) - (int)(h->heap2_begin);
+
+ pb_PosMode=fsAtMark;
+ pb_PosOffset=0;
+
+ error=PBWriteSync ((ParmBlkPtr)&pb);
+ if (error!=noErr){
+ PBCloseSync ((ParmBlkPtr)&pb);
+ heap_written_count=MAX_N_HEAPS;
+ return;
+ }
+ }
+
+ PBCloseSync ((ParmBlkPtr)&pb);
+}
diff --git a/pcompact.a b/pcompact.a
new file mode 100644
index 0000000..ee55b11
--- /dev/null
+++ b/pcompact.a
@@ -0,0 +1,1762 @@
+
+; mark used nodes and pointers in argument parts and link backward pointers
+
+
+ lea o0,heap_size_33
+ lwz d7,0(o0)
+
+ lea o0,caf_list
+ slwi d7,d7,5
+ lwz d0,0(o0)
+
+ stwu a4,-4(sp)
+ li g3,128
+
+ cmpwi 0,d0,0
+ beq end_mark_cafs
+
+mark_cafs_lp:
+ lwz d1,0(d0)
+ lwz o5,-4(d0)
+ addi a2,d0,4
+ slwi d0,d1,2
+ add a4,a2,d0
+
+ bl mark_stack_nodes
+
+ addic. d0,o5,0
+ bne mark_cafs_lp
+
+end_mark_cafs:
+
+ lea o0,stack_p
+ lwz a4,0(sp)
+ lwz a2,0(o0)
+ addi sp,sp,4
+
+ bl mark_stack_nodes
+
+ if MEASURE_GC
+ stwu o4,-4(sp)
+ bl .add_mark_compact_garbage_collect_time
+
+ lwz o4,0(sp)
+ li g3,128
+ baddi sp,4
+ endif
+
+ b compact_heap
+
+mark_stack_nodes3:
+ stw a0,-4(a2)
+ b mark_stack_nodes
+
+mark_stack_nodes2:
+ lwz g1,0(a0)
+ addi d0,a2,1-4
+ stw g1,-4(a2)
+ stw d0,0(a0)
+
+mark_stack_nodes:
+ cmpw 0,a4,a2
+ beq end_mark_nodes
+
+ lwz a0,0(a2)
+ addi a2,a2,4
+
+ sub d0,a0,d6
+ if SHARE_CHAR_INT
+ cmplw 0,d0,d7
+ bge- mark_stack_nodes
+ endif
+
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ bne- mark_stack_nodes2
+
+ li d3,0
+ li d5,1
+
+mark_arguments:
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+ srw o3,g3,o2
+
+ or o1,o1,o3
+
+ andi. r0,d0,2
+ lha d2,-2(d0)
+
+ stbx o1,o4,o0
+
+ cmpwi 6,d2,0
+ beq mark_lazy_node
+
+ beq 6,mark_hnf_0
+
+ cmplwi 0,d2,256
+ addi a0,a0,4
+ bge mark_record
+
+ subic. d2,d2,2
+ beq mark_hnf_2
+ blt mark_hnf_1
+
+mark_hnf_3:
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+mark_hnf_3_:
+ sub d0,a1,d6
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ srw o3,g3,o2
+ and. r0,o1,o3
+ bne shared_argument_part
+
+ or o1,o1,o3
+ stbx o1,o4,o0
+
+no_shared_argument_part:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ slwi d2,d2,2
+ ori o0,o0,1
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+
+ lwzux d2,a1,d2
+ li d5,0
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b mark_node
+
+shared_argument_part:
+ cmplw 0,a1,a0
+ bgt mark_hnf_1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+ stw o0,4-NODE_POINTER_OFFSET(a0)
+ b mark_hnf_1
+
+mark_lazy_node_1:
+; remove if no selectors:
+ bne mark_selector_node_1
+mark_hnf_1:
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,2
+ mr a0,d2
+ b mark_node
+
+mark_selector_node_1:
+ baddicc d2,3
+ lwz a1,0-NODE_POINTER_OFFSET(a0)
+ beq mark_indirection_node
+
+ addic. d2,d2,1
+ sub o2,a1,d6
+ ble mark_record_selector_node_1
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne mark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq mark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,2
+ ble small_tuple_or_record
+
+large_tuple_or_record:
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+
+ sub o2,d1,d6
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne mark_hnf_1
+
+small_tuple_or_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ andc o1,o1,o3
+
+ lwz g1,4(g1)
+ subi d2,a0,4
+
+ mtlr g1
+ stbx o1,o4,o0
+ mr a0,a1
+ stwu r0,-4(sp)
+ blrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ b mark_node
+
+mark_record_selector_node_1:
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ beq mark_strict_record_selector_node_1
+
+ rlwnm. r0,g1,g2,24,24
+ bne mark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq mark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble small_tuple_or_record
+ b large_tuple_or_record
+
+mark_strict_record_selector_node_1:
+ rlwnm. r0,g1,g2,24,24
+ bne mark_hnf_1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq mark_hnf_1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,258
+ ble select_from_small_record
+
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+ sub o2,d1,d6
+
+ srwi d2,o2,5
+ lbzx g1,o4,d2
+ rlwinm g2,o2,32-2,29,31
+ rlwnm. r0,g1,g2,24,24
+ bne mark_hnf_1
+
+select_from_small_record:
+ if LINUX
+ lwz g1,-8(d0)
+ mflr r0
+ else
+ lha g1,-6(d0)
+ mflr r0
+ lwzx g1,rtoc,g1
+ endif
+ subi a0,a0,4
+ lwz g1,4(g1)
+
+ mtlr g1
+ stwu r0,-4(sp)
+ blrl
+ mtlr r0
+
+ b mark_next_node
+
+mark_indirection_node:
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ mr a0,a1
+ b mark_node
+
+mark_hnf_2:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ lwzu d2,4-NODE_POINTER_OFFSET(a0)
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+
+mark_node:
+ sub d0,a0,d6
+ if SHARE_CHAR_INT
+ cmplw 0,d0,d7
+ bge- mark_next_node_after_static
+ endif
+ srwi o0,d0,5
+ lbzx o1,o4,o0
+ rlwinm o2,d0,32-2,29,31
+ rlwnm. r0,o1,o2,24,24
+ beq+ mark_arguments
+
+mark_next_node:
+ cmpwi 0,d5,0
+ bne mark_parent
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+
+ cmpwi 0,d5,3
+ beq argument_part_cycle1
+
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+c_argument_part_cycle1:
+ cmplw 0,a0,d3
+ bgt no_reverse_1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ addi d0,d3,4+1
+ stw o0,4-NODE_POINTER_OFFSET(d3)
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ clrrwi a0,d2,2
+ b mark_node
+
+no_reverse_1:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b mark_node
+
+mark_lazy_node:
+ beq 6,mark_next_node
+
+ bsubicc d2,1
+ baddi a0,4
+ ble mark_lazy_node_1
+
+ cmplwi 0,d2,255
+ bge mark_closure_with_unboxed_arguments
+
+mark_closure_with_unboxed_arguments_:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ slwi d2,d2,2
+ ori o0,o0,2
+ stw o0,0(a0)
+
+ lwzux d2,a0,d2
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+ b mark_node
+
+mark_closure_with_unboxed_arguments:
+; baddi d2,1
+ srwi d0,d2,8
+ bandic d2,255
+; bsub d2,d0
+ bsubc d2,d0
+; bsubicc d2,1
+ bgt mark_closure_with_unboxed_arguments_
+ beq mark_hnf_1
+ bsubi a0,4
+ b mark_next_node
+
+mark_hnf_0:
+ if SHARE_CHAR_INT
+ cmpw d0,int_reg
+ bne no_int_3
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ cmplwi 0,d2,33
+ bge mark_next_node
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ lea a0,small_integers
+ slwi d2,d2,3
+ add a0,a0,d2
+ b mark_next_node_after_static
+
+no_int_3:
+ cmplw d0,char_reg
+ bne no_char_3
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+
+ lbz d2,7-NODE_POINTER_OFFSET(a0)
+ lea a0,static_characters
+ slwi d2,d2,3
+ add a0,a0,d2
+ b mark_next_node_after_static
+
+no_char_3:
+ blt no_normal_hnf_0
+
+ subi a0,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET
+
+ andc o1,o1,o3
+ stbx o1,o4,o0
+ b mark_next_node_after_static
+
+no_normal_hnf_0:
+ endif
+
+ lea o0,__ARRAY__2
+ cmplw 0,d0,o0
+ bne+ mark_next_node
+ b mark_array
+
+mark_record:
+ subic. d2,d2,258
+ beq mark_record_2
+ blt mark_record_1
+
+mark_record_3:
+ lhz d2,-2+2(d0)
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ subic. d2,d2,1
+ blt mark_record_3_bb
+
+ beq mark_record_3_ab
+
+ subic. d2,d2,1
+ beq mark_record_3_aab
+
+ b mark_hnf_3_
+
+mark_record_3_bb:
+ subi a0,a0,4
+
+ sub d0,a1,d6
+ setmbit o4,d0,d1,o0,o1,o2,2
+
+ cmplw a1,a0
+ bgt mark_next_node
+
+ srwi. o0,o0,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,8+2+1
+ stw o2,8-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ not_next_byte_1
+
+ addi d1,d1,1
+ lbzx o1,o4,d1
+ li o0,128
+not_next_byte_1:
+ and. r0,o1,o0
+ beq+ not_yet_linked_bb
+
+ sub d0,a0,d6
+ addi d0,d0,8
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b mark_next_node
+
+not_yet_linked_bb:
+ or o1,o1,o0
+ stbx o1,o4,d1
+ b mark_next_node
+
+mark_record_3_ab:
+ sub d0,a1,d6
+ setmbit o4,d0,d1,o0,o1,o2,2
+
+ cmplw 0,a1,a0
+ bgt mark_hnf_1
+
+ srwi. o0,o0,1
+
+ lwz o2,0-NODE_POINTER_OFFSET(a1)
+ addi d0,a0,4+2+1
+ stw o2,4-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+ bne+ not_next_byte_2
+
+ addi d1,d1,1
+ lbzx o1,o4,d1
+ li o0,128
+not_next_byte_2:
+ and. r0,o1,o0
+ beq+ not_yet_linked_ab
+
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b mark_hnf_1
+
+not_yet_linked_ab:
+ or o1,o1,o0
+ stbx o1,o4,d1
+ b mark_hnf_1
+
+mark_record_3_aab:
+ sub d0,a1,d6
+
+ tstmbit o4,d0,d1,o0,o1,o2,2
+ bne shared_argument_part
+
+ srw o0,g3,o2
+ or o1,o1,o0
+ stbx o1,o4,d1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ li d5,1
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b mark_node
+
+mark_record_2:
+ lhz g1,-2+2(d0)
+ cmplwi g1,1
+ bgt mark_hnf_2
+ beq mark_hnf_1
+
+ subi a0,a0,4
+ b mark_next_node
+
+mark_record_1:
+ lhz g1,-2+2(d0)
+ tst g1
+ bne mark_hnf_1
+
+ subi a0,a0,4
+ b mark_next_node
+
+mark_array:
+ lwz d1,8-NODE_POINTER_OFFSET(a0)
+ tst d1
+ beq mark_lazy_array
+
+ lhz d0,-2(d1)
+ tst d0
+ beq mark_b_record_array
+
+ lhz d1,-2+2(d1)
+ tst d1
+ beq mark_b_record_array
+
+ subi d0,d0,256
+ cmpw 0,d0,d1
+ beq mark_a_record_array
+
+mark_ab_record_array:
+ mr o2,d2
+ mr o3,d3
+ stw d5,-4(sp)
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ stw a0,-8(sp)
+
+ slwi d2,d2,2
+ mullw a1,d2,d0
+
+ sub d0,d0,d1
+ addi a0,a0,4
+ add a1,a1,a0
+
+ mflr r0
+ stw r0,-12(sp)
+ bl reorder
+ lwz r0,-12(sp)
+
+ lwz a0,-8(sp)
+ mtlr r0
+
+ lwz d0,-4(a0)
+ mullw d0,d0,d1
+
+ lwz d5,-4(sp)
+ mr d3,o3
+ mr d2,o2
+ b mark_lr_array
+
+mark_b_record_array:
+ sub d0,a0,d6
+ addi d0,d0,4
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b mark_next_node
+
+mark_a_record_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+ mullw d0,d0,d1
+ b mark_lr_array
+
+mark_lazy_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi a0,a0,8
+mark_lr_array:
+ sub d1,a0,d6
+ srwi d1,d1,2
+ add d1,d1,d0
+ setmbit o4,d1,d2,o0,o1,o2,0
+
+ cmplwi 0,d0,1
+ ble mark_array_length_0_1
+
+ mr a1,a0
+ slwi d0,d0,2
+ add a0,a0,d0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a0)
+ lwzu o0,-4-NODE_POINTER_OFFSET(a1)
+ addi d2,d2,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+ b mark_node
+
+mark_array_length_0_1:
+ subi a0,a0,8
+ blt mark_next_node
+
+ lwz d1,12-NODE_POINTER_OFFSET(a0)
+ lwz o0,8-NODE_POINTER_OFFSET(a0)
+ lwz o1,4-NODE_POINTER_OFFSET(a0)
+ stw o0,12-NODE_POINTER_OFFSET(a0)
+ stw o1,8-NODE_POINTER_OFFSET(a0)
+ stwu d1,4-NODE_POINTER_OFFSET(a0)
+ b mark_hnf_1
+
+
+mark_parent:
+ tst d3
+ beq mark_stack_nodes2
+
+ subic. d5,d5,1
+ beq argument_part_parent
+
+ cmplw a0,d3
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ bgt no_reverse_2
+
+ mr a1,a0
+ addi d0,d3,1
+ lwz a0,0-NODE_POINTER_OFFSET(a1)
+ stw d0,0-NODE_POINTER_OFFSET(a1)
+
+no_reverse_2:
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b mark_next_node
+
+argument_part_parent:
+ mr a1,d3
+ mr d3,a0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+
+ mr a0,a1
+
+skip_upward_pointers:
+ andi. d0,d2,3
+ cmpwi 0,d0,3
+ bne no_upward_pointer
+
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ b skip_upward_pointers
+
+no_upward_pointer:
+ cmplw 0,d3,a0
+ bgt no_reverse_3
+
+ mr a6,d3
+ lwz d3,0-NODE_POINTER_OFFSET(d3)
+ addi d0,a0,1
+ stw d0,0-NODE_POINTER_OFFSET(a6)
+
+no_reverse_3:
+ stw d3,0-NODE_POINTER_OFFSET(a1)
+
+ clrrwi d3,d2,2
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+
+ cmplw 6,a0,d3
+
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+ bgt 6,no_reverse_4
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ stw o0,4-NODE_POINTER_OFFSET(d3)
+ addi d0,d3,4+2+1
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ clrrwi a0,d2,2
+ b mark_node
+
+no_reverse_4:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b mark_node
+
+argument_part_cycle1:
+ mr d1,a1
+
+skip_pointer_list1:
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. d5,d2,3
+ cmpwi 0,d5,3
+ beq skip_pointer_list1
+
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ mr a1,d1
+ b c_argument_part_cycle1
+
+ if SHARE_CHAR_INT
+mark_next_node_after_static:
+ cmpwi 0,d5,0
+ bne mark_parent_after_static
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+
+ cmpwi 0,d5,3
+ beq argument_part_cycle2
+
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+c_argument_part_cycle2:
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b mark_node
+
+mark_parent_after_static:
+ cmpwi 0,d3,0
+ beq mark_stack_nodes3
+
+ subic. d5,d5,1
+ beq argument_part_parent_after_static
+
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b mark_next_node
+
+argument_part_parent_after_static:
+ mr a1,d3
+ mr d3,a0
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+
+ mr a0,a1
+
+skip_upward_pointers_2:
+ andi. d0,d2,3
+ cmpwi 0,d0,3
+ bne no_reverse_3
+
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ b skip_upward_pointers_2
+
+argument_part_cycle2:
+ mr d1,a1
+
+skip_pointer_list2:
+ clrrwi a1,d2,2
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. d5,d2,3
+ cmpwi 0,d5,3
+ beq skip_pointer_list2
+
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ mr a1,d1
+ b c_argument_part_cycle2
+ endif
+
+end_mark_nodes:
+ addi a2,a2,4
+ blr
+
+
+; compact the heap
+
+compact_heap:
+
+ if FINALIZERS
+ lea a0,finalizer_list
+ lea a1,free_finalizer_list
+
+ lwz a2,0(a0)
+determine_free_finalizers_after_compact1:
+ lea o0,__Nil_m8
+ cmplw o0,a2
+ beq end_finalizers_after_compact1
+
+ sub d1,a2,d6
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ beq finalizer_not_used_after_compact1
+
+ lwz d0,0(a2)
+ mr a3,a2
+ b finalizer_find_descriptor
+
+finalizer_find_descriptor_lp:
+ clrrwi d0,d0,2
+ mr a3,d0
+ lwz d0,0(d0)
+finalizer_find_descriptor:
+ andi. r0,d0,1
+ bne finalizer_find_descriptor_lp
+
+ lea o0,e____system__kFinalizerGCTemp_2
+ stw o0,0(a3)
+
+ cmplw a2,a0
+ bgt finalizer_no_reverse
+
+ lwz d0,0(a2)
+ addi a3,a0,1
+ stw a3,0(a2)
+ stw d0,0(a0)
+
+finalizer_no_reverse:
+ addi a0,a2,4
+ lwz a2,4(a2)
+ b determine_free_finalizers_after_compact1
+
+finalizer_not_used_after_compact1:
+ lea o0,e____system__kFinalizerGCTemp_2
+ stw o0,0(a2)
+
+ stw a2,0(a1)
+ addi a1,a2,4
+
+ lwz a2,4(a2)
+ stw a2,0(a0)
+ b determine_free_finalizers_after_compact1
+
+end_finalizers_after_compact1:
+ stw a2,0(a1)
+
+ lea o1,finalizer_list
+ lwz a0,0(o1)
+ lea o0,__Nil_m8
+ cmplw o0,a0
+ beq finalizer_list_empty
+ andi. r0,a0,3
+ bne finalizer_list_already_reversed
+ lwz d0,0(a0)
+ addi o0,o1,1
+ stw o0,0(a0)
+ stw d0,0(o1)
+finalizer_list_already_reversed:
+finalizer_list_empty:
+
+ lea a2,free_finalizer_list
+ lea o0,__Nil_m8
+ lwz o1,0(a2)
+ cmplw o0,o1
+ beq free_finalizer_list_empty
+
+ stwu a4,-4(sp)
+ addi a4,a2,4
+ bl mark_stack_nodes
+ lwz a4,0(sp)
+ addi sp,sp,4
+
+free_finalizer_list_empty:
+ endif
+
+ lea o0,heap_size_33
+ lwz d5,0(o0)
+ slwi d2,d5,5
+
+ if SHARE_CHAR_INT
+ add d2,d2,d6
+ endif
+
+ addi d5,d5,3
+ srwi. d5,d5,2
+
+ mr a2,o4
+ mr a6,d6
+ li d4,0
+
+ beq end_compact_heap
+
+ mtctr d5
+skip_zeros_2:
+ lwz d4,0(a2)
+ baddi a2,4
+ cmpwi 0,d4,0
+ bne end_skip_zeros
+find_non_zero_long_2:
+ bdnz skip_zeros_2
+
+ b end_compact_heap
+
+end_skip_zeros:
+ sub d7,a2,o4
+ subi d7,d7,4
+ slwi d7,d7,5
+ add d7,d7,d6
+
+skip_zero_bits:
+ cntlzw d1,d4
+ cmpwi 0,d1,32
+ beq- find_non_zero_long_2
+
+ addi d1,d1,1
+ slw d4,d4,d1
+ slwi d1,d1,2
+ add d7,d7,d1
+
+ lwz d0,-4(d7)
+ mr a0,d7
+
+ andi. r0,d0,2
+ clrrwi d0,d0,2
+ beq+ begin_update_list_2
+
+ lwz d3,-8(d0)
+ mr a1,d0
+ andi. r0,d3,1
+ beq end_list_2
+find_descriptor_2:
+ clrrwi a1,d3,2
+ lwz d3,0(a1)
+ andi. r0,d3,1
+ bne find_descriptor_2
+end_list_2:
+ lhz d1,-2(d3)
+
+ cmplwi 0,d1,256
+ blt no_record_arguments
+
+ lhz d3,-2+2(d3)
+ subic. d3,d3,2
+ bge copy_record_arguments_aa
+
+ subi d1,d1,256+3
+
+copy_record_arguments_all_b:
+ mr g2,d1
+
+update_up_list_1r:
+ mr a1,d0
+ sub d0,d0,d6
+
+ tstmbit o4,d0,d1,o0,o1,o2,2
+ beq copy_argument_part_1r
+
+ lwz d0,0(a1)
+ stw a6,0(a1)
+ subi d0,d0,3
+ b update_up_list_1r
+
+copy_argument_part_1r:
+ lwz d0,0(a1)
+ stw a6,0(a1)
+ stw d0,0(a6)
+ addi a6,a6,4
+
+ mr d1,g2
+
+copy_b_record_argument_part_arguments:
+ lwz o0,0(a0)
+
+ subic. d1,d1,1
+
+ addi a0,a0,4
+ stw o0,0(a6)
+ addi a6,a6,4
+ bge copy_b_record_argument_part_arguments
+
+ sub o0,a2,o4
+ slwi o0,o0,5
+ add o0,o0,d6
+
+ cmpw 0,o0,d7
+ addi d7,d7,4
+ slwi d4,d4,1
+ bne skip_zero_bits
+
+ bdz end_compact_heap
+
+ lwz d4,0(a2)
+ lis o1,0x8000
+ andc d4,d4,o1
+ b skip_zeros_2+4
+
+copy_record_arguments_aa:
+ subi d1,d1,256+2
+ sub d1,d1,d3
+ mr g2,d1
+
+update_up_list_2r:
+ mr a1,d0
+ lwz d0,0(a1)
+ andi. d1,d0,3
+ subic. d1,d1,3
+ stw a6,0(a1)
+ bne copy_argument_part_2r
+
+ subi d0,d0,3
+ b update_up_list_2r
+
+copy_argument_part_2r:
+ cmplw 0,d0,a0
+ blt copy_record_argument_2
+ if SHARE_CHAR_INT
+ cmplw 0,d0,d2
+ bge copy_record_argument_2
+ endif
+ mr a1,d0
+ lwz d0,0(a1)
+ addi d1,a6,1
+ stw d1,0(a1)
+copy_record_argument_2:
+ stw d0,0(a6)
+ addi a6,a6,4
+
+ subic. d3,d3,1
+ blt no_pointers_in_record
+copy_record_pointers:
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt copy_record_pointers_2
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_record_pointers_2
+ endif
+ lwz d1,0(a1)
+ addi d0,a6,1
+ stw d0,0(a1)
+ mr a1,d1
+copy_record_pointers_2:
+ stw a1,0(a6)
+ subic. d3,d3,1
+ addi a6,a6,4
+ bge copy_record_pointers
+
+no_pointers_in_record:
+ cmpwi 0,g2,0
+ subi d1,g2,1
+ beq no_non_pointers_in_record
+
+copy_non_pointers_in_record:
+ lwz o0,0(a0)
+ addi a0,a0,4
+ stw o0,0(a6)
+# subi. d2,d2,1
+ subic. d1,d1,1
+ addi a6,a6,4
+ bge copy_non_pointers_in_record
+
+no_non_pointers_in_record:
+ b skip_zero_bits
+
+no_record_arguments:
+ subi d1,d1,3
+update_up_list_2:
+ mr a1,d0
+ lwz d0,0(a1)
+ andi. d3,d0,3
+ cmpwi 0,d3,3
+ bne copy_argument_part_2
+
+ stw a6,0(a1)
+ clrrwi d0,d0,2
+ b update_up_list_2
+
+copy_argument_part_2:
+ stw a6,0(a1)
+
+ cmplw 0,d0,a0
+ addi a6,a6,4
+ blt copy_arguments_1
+
+ if SHARE_CHAR_INT
+ cmplw 0,d0,d2
+ bge copy_arguments_1
+ endif
+ mr a1,d0
+ lwz d0,0(a1)
+ addi d3,a6,1-4
+ stw d3,0(a1)
+copy_arguments_1:
+ stw d0,-4(a6)
+
+copy_argument_part_arguments:
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt copy_arguments_2
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_arguments_2
+ endif
+ ori d0,a6,1
+ lwz d3,0(a1)
+ stw d0,0(a1)
+ mr a1,d3
+
+copy_arguments_2:
+ stw a1,0(a6)
+ subic. d1,d1,1
+ addi a6,a6,4
+ bge copy_argument_part_arguments
+
+ b skip_zero_bits
+
+update_list_2:
+ stw a6,0(a1)
+begin_update_list_2:
+ mr a1,d0
+ lwz d0,0(a1)
+update_list__2:
+ andi. r0,d0,1
+ beq end_update_list_2
+ andi. r0,d0,2
+ clrrwi d0,d0,2
+ beq update_list_2
+ mr a1,d0
+ lwz d0,0(a1)
+ b update_list__2
+
+end_update_list_2:
+ stw a6,0(a1)
+
+ andi. r0,d0,2
+ stw d0,0(a6)
+ beq move_lazy_node
+
+ lhz d1,-2(d0)
+ baddi a6,4
+ cmpwi 0,d1,0
+ beq move_hnf_0
+
+ cmplwi 0,d1,256
+ bge move_record
+
+ subic. d1,d1,2
+ blt move_hnf_1
+ beq move_hnf_2
+
+move_hnf_3:
+ lwz a1,0(a0)
+ addi a0,a0,4
+move_hnf_3_:
+ cmplw 0,a1,a0
+ blt copy_hnf_3_1
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_hnf_3_1
+ endif
+ ori d0,a6,1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+copy_hnf_3_1:
+ stw a1,0(a6)
+
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt copy_hnf_3_2
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_hnf_3_2
+ endif
+ addi d0,a6,4+2+1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+copy_hnf_3_2:
+ stw a1,4(a6)
+ addi a6,a6,8
+ b skip_zero_bits
+
+move_hnf_2:
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt copy_hnf_2_1
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_hnf_2_1
+ endif
+ ori d0,a6,1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+copy_hnf_2_1:
+ stw a1,0(a6)
+
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt copy_hnf_2_2
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge copy_hnf_2_2
+ endif
+ addi d0,a6,4+1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+copy_hnf_2_2:
+ stw a1,4(a6)
+ addi a6,a6,8
+ b skip_zero_bits
+
+move_hnf_1:
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt move_hnf_1_
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge move_hnf_1_
+ endif
+ ori d0,a6,1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+move_hnf_1_:
+ stw a1,0(a6)
+ addi a6,a6,4
+ b skip_zero_bits
+
+move_real_or_file:
+ lwz o0,0(a0)
+ lwz o1,4(a0)
+ stw o0,0(a6)
+ stw o1,4(a6)
+ addi a6,a6,8
+ b skip_zero_bits
+
+move_int_bool_or_char:
+ lwz o0,0(a0)
+ addi a6,a6,4
+ stw o0,-4(a6)
+copy_normal_hnf_0:
+ b skip_zero_bits
+
+move_hnf_0:
+ cmplw 0,d0,int_reg
+ blt move_real_file_string_or_array
+
+ cmplw 0,d0,char_reg
+ ble move_int_bool_or_char
+
+; b,a copy_normal_hnf_0
+ b skip_zero_bits
+
+move_real_file_string_or_array:
+ lea o0,__STRING__2
+ cmplw 0,d0,o0
+ bgt move_real_or_file
+
+ bne move_array
+
+ lwz d0,0(a0)
+ addi d0,d0,3
+ srwi d0,d0,2
+
+cp_s_arg_lp3:
+ lwz o0,0(a0)
+ subic. d0,d0,1
+ stw o0,0(a6)
+ blt end_cp_s_lp3
+
+cp_s_lp3:
+ lwzu o0,4(a0)
+ subic. d0,d0,1
+ stwu o0,4(a6)
+ bge cp_s_lp3
+
+end_cp_s_lp3:
+ addi a6,a6,4
+ b skip_zero_bits
+
+move_record:
+ bsubicc d1,258
+ blt move_record_1
+ beq move_record_2
+
+move_record_3:
+ lhz d1,-2+2(d0)
+
+ lwz a1,0(a0)
+
+ bsubicc d1,1
+
+ baddi a0,4
+
+ bgt move_hnf_3_
+
+ blt move_record_3_1b
+
+move_record_3_1a:
+ cmplw 0,a1,a0
+ blt move_record_3_1b
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge move_record_3_1b
+ endif
+ addi d0,a6,1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+move_record_3_1b:
+ stw a1,0(a6)
+ addi a6,a6,4
+
+ lwz a1,0(a0)
+ addi a0,a0,4
+ cmplw 0,a1,a0
+ blt move_record_3_2
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge move_record_3_2
+ endif
+ sub d0,a1,d6
+ addi d0,d0,4
+
+ tstmbit o4,d0,d1,o0,o1,o2,2
+ beq not_linked_record_argument_part_3_b
+
+ sub d0,a6,d6
+ setmbit o4,d0,d1,o0,o1,o2,2
+ b linked_record_argument_part_3_b
+
+not_linked_record_argument_part_3_b:
+ srw o0,g3,o2
+ or o1,o1,o0
+ stbx o1,o4,d1
+
+ sub d0,a6,d6
+ clrmbit o4,d0,d1,o0,o1,o2,2
+
+linked_record_argument_part_3_b:
+ lwz d1,0(a1)
+ addi d0,a6,2+1
+ stw d0,0(a1)
+ mr a1,d1
+move_record_3_2:
+ stw a1,0(a6)
+ addi a6,a6,4
+
+ sub o0,a2,o4
+ slwi o0,o0,5
+ add o0,o0,d6
+
+ addi d7,d7,4
+ cmpw 0,d7,o0
+
+ addi d7,d7,4
+ slwi d4,d4,2
+ blt skip_zero_bits
+ bgt bits_in_next_long
+
+ lis o1,0x80000000>>16
+ b one_bit_in_next_long
+
+bits_in_next_long:
+ lis o1,0xc0000000>>16
+one_bit_in_next_long:
+ bdz end_compact_heap
+
+ lwz d4,0(a2)
+ andc d4,d4,o1
+ b skip_zeros_2+4
+
+move_record_2:
+ lhz g1,-2+2(d0)
+ cmplwi 0,g1,1
+ bgt move_hnf_2
+ blt move_real_or_file
+
+move_record_2_ab:
+ lwz a1,0(a0)
+ lwzu o0,4(a0)
+ cmplw 0,a1,a0
+ blt move_record_2_1
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ addi d0,a6,1
+ bge move_record_2_1
+ endif
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+move_record_2_1:
+ stw a1,0(a6)
+ stw o0,4(a6)
+ addi a6,a6,8
+ b skip_zero_bits
+
+move_record_1:
+ lhz g1,-2+2(d0)
+ cmpwi 0,g1,0
+ bne move_hnf_1
+
+ b move_int_bool_or_char
+
+skip_zeros_2_a:
+ lwz d4,0(a2)
+ bdz- out_of_memory_4
+ cmpwi 0,d4,0
+ addi a2,a2,4
+ beq skip_zeros_2_a
+
+end_skip_zeros_a:
+ sub d7,a2,o4
+ subi d7,d7,4
+ slwi d7,d7,5
+ add d7,d7,d6
+
+move_array:
+skip_zero_bits_a:
+ cntlzw d1,d4
+ cmpwi 0,d1,32
+ beq skip_zeros_2_a
+
+ slw d4,d4,d1
+ slwi d4,d4,1
+
+ slwi d1,d1,2
+ add d7,d7,d1
+
+ cmpw 0,d7,a0
+ mr d1,d7
+ addi d7,d7,4
+ bne move_a_array
+
+move_b_array:
+ lwz a1,0(a0)
+ lwzu d1,4(a0)
+ stw a1,0(a6)
+ lhz d0,-2(d1)
+
+ addi a6,a6,4
+
+ cmpwi 0,d0,0
+ beq move_strict_basic_array
+
+ subi d1,d0,256
+ mullw d0,a1,d1
+ b cp_s_arg_lp3
+
+move_strict_basic_array:
+ cmpw 0,d1,int_reg
+ mr d0,a1
+ beq cp_s_arg_lp3
+
+ cmpw 0,d1,bool_reg
+ beq move_bool_array
+
+ add d0,d0,d0
+ b cp_s_arg_lp3
+
+move_bool_array:
+ addi d0,d0,3
+ srwi d0,d0,2
+ b cp_s_arg_lp3
+
+move_a_array:
+ mr a1,d1
+ sub d1,d1,a0
+ srwi d1,d1,2
+ subic. d1,d1,1
+ blt skip_zero_bits
+ if 0
+ cmpwi d1,1
+ ble move_a_array_size_0_1
+ endif
+
+; first swap second last element of array and second last element of header
+ lwz o0,0(a0)
+ lwz d0,-4(a1)
+ stw o0,-4(a1)
+ stw d0,0(a6)
+
+; then swap last element of array and last element of header
+; this also works for length 0 and 1 !
+
+ lwz d0,0(a1)
+ lwz o0,4(a0)
+ stw o0,0(a1)
+ addi a0,a0,8
+ if 0
+ c_move_array_size_1:
+ endif
+
+ cmpwi 0,d0,0
+ stw d0,4(a6)
+ addi a6,a6,8
+ beq st_move_array_lp
+
+ lhz d3,-2+2(d0)
+ lhz d0,-2(d0)
+ subi d0,d0,256
+ cmpw 0,d0,d3
+ beq st_move_array_lp
+
+move_array_ab:
+ mr o2,d4
+ mr o3,d5
+
+ mr g2,d2
+ stw a0,-4(sp)
+
+ lwz d2,-8(a6)
+ mr d1,d3
+
+ mr d3,d0
+ slwi d2,d2,2
+ mullw a1,d2,d3
+
+ sub d0,d0,d1
+ add a1,a1,a0
+
+ mflr r0
+ stw r0,-8(sp)
+
+ bl reorder
+
+ lwz r0,-8(sp)
+ lwz d3,-8(a6)
+ mtlr r0
+
+ lwz a0,-4(sp)
+ mr d2,g2
+ subi d1,d1,1
+ subi d0,d0,1
+ b st_move_array_lp_ab
+
+move_array_ab_lp1:
+ mr d4,d1
+move_array_ab_a_elements:
+ lwz d5,0(a0)
+ addi a0,a0,4
+ cmplw 0,d5,a0
+ blt move_array_element_ab
+ if SHARE_CHAR_INT
+ cmplw 0,d5,d2
+ bge move_array_element_ab
+ endif
+ mr a1,d5
+ lwz d5,0(a1)
+ addi o0,a6,1
+ stw o0,0(a1)
+move_array_element_ab:
+ subic. d4,d4,1
+ stw d5,0(a6)
+ addi a6,a6,4
+ bge move_array_ab_a_elements
+
+ mr d4,d0
+move_array_ab_b_elements:
+ lwz o0,0(a0)
+ subic. d4,d4,1
+ addi a0,a0,4
+ stw o0,0(a6)
+ addi a6,a6,4
+ bge move_array_ab_b_elements
+st_move_array_lp_ab:
+ subic. d3,d3,1
+ bge move_array_ab_lp1
+
+ mr d5,o3
+ mr d4,o2
+ b skip_zero_bits
+
+st_move_array_lp:
+ subic. d1,d1,1
+ subi a6,a6,4
+ bge+ move_lazy_node_arguments
+ addi a6,a6,4
+ b skip_zero_bits
+ if 0
+ move_a_array_size_0_1:
+ lwz o0,0(a0)
+ lwz d0,4(a0)
+ blt move_array_size_0
+
+ stw d0,0(a6)
+ lwz d0,8(a0)
+ stwu o0,8(a0)
+ b c_move_array_size_1
+
+ move_array_size_0:
+ stw o0,0(a6)
+ stw d0,4(a6)
+ addi a6,a6,8
+ b skip_zero_bits
+ endif
+
+move_lazy_node:
+ lha d1,-2(d0)
+ mr a1,d0
+ cmpwi 0,d1,0
+ beq move_lazy_node_0
+
+ bsubicc d1,1
+ ble move_lazy_node_1
+
+ cmplwi 0,d1,256
+ bge move_closure_with_unboxed_arguments
+
+move_lazy_node_arguments:
+ lwz a1,0(a0)
+ baddi a0,4
+ cmplw 0,a1,a0
+ blt move_lazy_node_arguments_
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge move_lazy_node_arguments_
+ endif
+ lwz o0,0(a1)
+
+ bsubicc d1,1
+
+ stwu o0,4(a6)
+ addi d0,a6,1
+ stw d0,0(a1)
+ bge move_lazy_node_arguments
+
+ baddi a6,4
+ b skip_zero_bits
+
+move_lazy_node_arguments_:
+ bsubicc d1,1
+ stwu a1,4(a6)
+ bge move_lazy_node_arguments
+
+ baddi a6,4
+ b skip_zero_bits
+
+move_lazy_node_1:
+ lwz a1,0(a0)
+ baddi a0,4
+ cmplw 0,a1,a0
+ blt move_lazy_node_1_
+ if SHARE_CHAR_INT
+ cmplw 0,a1,d2
+ bge move_lazy_node_1_
+ endif
+ addi d0,a6,4+1
+ lwz d1,0(a1)
+ stw d0,0(a1)
+ mr a1,d1
+move_lazy_node_1_:
+ stw a1,4(a6)
+move_lazy_node_0:
+ baddi a6,12
+ b skip_zero_bits
+
+move_closure_with_unboxed_arguments:
+ baddi d1,1
+ srwi d0,d1,8
+ beq move_closure_with_unboxed_arguments_1
+ bandic d1,255
+ bsubc d1,d0
+ beq copy_non_pointers_of_closure
+
+move_pointers_in_closure:
+ lwz a1,0(a0)
+ baddi a0,4
+ cmplw 6,a1,a0
+
+ bsubicc d1,1
+
+ blt 6,move_pointers_in_closure_
+ if SHARE_CHAR_INT
+ cmplw 6,a1,d2
+ bge 6,move_pointers_in_closure_
+ endif
+ lwz o0,0(a1)
+ addi o1,a6,4+1
+ stw o1,0(a1)
+ mr a1,o0
+
+move_pointers_in_closure_:
+ stwu a1,4(a6)
+ bne move_pointers_in_closure
+
+copy_non_pointers_of_closure:
+ bsubicc d0,1
+
+ lwz d1,0(a0)
+ baddi a0,4
+ stwu d1,4(a6)
+
+ bne copy_non_pointers_of_closure
+
+ baddi a6,4
+ b skip_zero_bits
+
+move_closure_with_unboxed_arguments_1:
+ lwz d0,0(a0)
+ baddi a6,12
+ stw d0,4-12(a6)
+ b skip_zero_bits
+
+end_compact_heap:
+
+ if FINALIZERS
+ lea a0,finalizer_list
+ lwz a0,0(a0)
+
+restore_finalizer_descriptors:
+ lea o0,__Nil_m8
+ cmplw o0,a0
+ beq end_restore_finalizer_descriptors
+
+ lea o0,e____system__kFinalizer_2
+ stw o0,0(a0)
+ lwz a0,4(a0)
+ b restore_finalizer_descriptors
+
+end_restore_finalizer_descriptors:
+ endif
diff --git a/pcopy.a b/pcopy.a
new file mode 100644
index 0000000..fcf61c1
--- /dev/null
+++ b/pcopy.a
@@ -0,0 +1,1000 @@
+
+NODE_POINTER_OFFSET set 0
+
+ lea o0,heap_p2
+ lea o1,stack_p
+ lwz a6,0(o0)
+ lwz a2,0(o1)
+
+ if COPIED_VECTOR
+ lea o0,heap_size_129
+ lwz d7,0(o0)
+ lea o0,heap_p1
+ slwi d7,d7,6
+ lwz a3,0(o0)
+ else
+ lea o0,heap_size
+ lwz d7,0(o0)
+ srwi d7,d7,1
+ endif
+ add o4,a6,d7
+
+ if WRITE_HEAP
+ lea o0,heap2_begin_and_end
+ stw o4,4(o0)
+ endif
+
+ lea o0,caf_list
+
+ if USE_DCBZ
+ li g3,32
+ li o3,-32
+ endif
+ lwz d0,0(o0)
+ cmpwi 0,d0,0
+ beq end_copy_cafs
+
+copy_cafs_lp:
+ lwz o5,-4(d0)
+ lwz d5,0(d0)
+ addi a2,d0,4
+ subi d5,d5,1
+ bl copy_lp2
+
+ addic. d0,o5,0
+ bne copy_cafs_lp
+
+end_copy_cafs:
+
+ lea o0,stack_p
+ lwz a2,0(o0)
+
+ sub d5,a4,a2
+ subic. d5,d5,4
+ srwi d5,d5,2
+
+ bgel copy_lp2
+
+ lea o0,heap_p2
+ lwz a2,0(o0)
+
+;
+; Copy all referenced nodes to the other semi space
+;
+
+ lea g2,copy_lp1
+
+copy_lp1:
+ cmplw 0,a2,a6
+ bge end_copy1
+
+ lwz d0,0(a2)
+ mtlr g2
+
+ baddi a2,4
+ andi. o0,d0,2
+
+ lha d5,-2(d0)
+
+ beq not_in_hnf_1
+
+in_hnf_1:
+ cmpwi 0,d5,0
+ beq copy_array_21
+
+ cmpwi 0,d5,2
+ ble b_copy_lp2
+
+ cmplwi 0,d5,256
+ bge copy_record_1
+
+ lwz o0,4(a2)
+ mr d6,d5
+
+ andi. r0,o0,1
+ bne node_without_arguments_part
+
+ li d5,0
+ bl copy_lp2
+
+ mtlr g2
+
+ baddi a2,4
+ subi d5,d6,2
+ b copy_lp2
+
+node_without_arguments_part:
+ clrrwi o0,o0,1
+ stw o0,4(a2)
+ li d5,0
+ bl copy_lp2
+
+ baddi a2,4
+ b copy_lp1
+
+copy_record_1:
+ subic. d5,d5,258
+ bgt copy_record_arguments_3
+
+ lhz d5,-2+2(d0)
+ blt copy_record_arguments_1
+
+ subic. d5,d5,1
+ bgt copy_lp2
+
+ beq- copy_node_arity1
+
+ baddi a2,8
+ b copy_lp1
+
+copy_record_arguments_1:
+ cmpwi d5,0
+ li d5,0
+ bne copy_lp2
+ baddi a2,4
+ b copy_lp1
+
+copy_record_arguments_3:
+ if COPIED_VECTOR
+ lwz o1,4(a2)
+ andi. r0,o1,1
+ lhz d1,-2+2(d0)
+ cmpwi 6,d1,0
+ bne record_node_without_arguments_part
+ else
+ lhz d1,-2+2(d0)
+ cmpwi 6,,d1,0
+ endif
+ baddi d5,2+1
+ beq 6,copy_record_arguments_3b
+
+ subic. d6,d1,1
+ beq copy_record_arguments_3abb
+
+ slwi d5,d5,2
+ add d4,a2,d5
+
+ li d5,0
+ bl copy_lp2
+
+ baddi a2,4
+ subi d5,d6,1
+ bl copy_lp2
+
+ mr a2,d4
+ b copy_lp1
+
+copy_record_arguments_3abb:
+ subi d5,d5,1
+ slwi d6,d5,2
+ li d5,0
+ bl copy_lp2
+
+ add a2,a2,d6
+ b copy_lp1
+
+copy_record_arguments_3b:
+ slwi d5,d5,2
+ add a2,a2,d5
+ b copy_lp1
+
+ if COPIED_VECTOR
+record_node_without_arguments_part:
+ clrrwi o1,o1,1
+ stw o1,4(a2)
+
+ baddi a2,8
+ beq 6,copy_lp1
+
+ subi a2,a2,8
+ li d5,0
+ bl copy_lp2
+
+ baddi a2,4
+ b copy_lp1
+ endif
+
+not_in_hnf_1:
+ cmpwi 0,d5,257
+ bge copy_unboxed_closure_arguments
+
+ subic. d5,d5,1
+ bgt copy_lp2
+
+copy_node_arity1:
+ li d5,0
+ bl copy_lp2
+
+ baddi a2,4
+ b copy_lp1
+
+copy_unboxed_closure_arguments:
+ srwi d4,d5,8
+ rlwinm d5,d5,0,24,31
+
+ beq copy_unboxed_closure_arguments1
+
+ bsubc d5,d4
+ bsubi d5,1
+ bnel+ copy_lp2
+
+ slwi d4,d4,2
+ badd a2,d4
+ b copy_lp1
+
+copy_unboxed_closure_arguments1:
+ baddi a2,8
+ b copy_lp1
+
+copy_array_21:
+ lwz d1,4(a2)
+ cmpwi 0,d1,0
+
+ lwz d5,0(a2)
+ baddi a2,8
+ beq copy_array_21_a
+
+ lhz d0,-2(d1)
+ subi d0,d0,256
+
+ lhz d1,-2+2(d1)
+ cmpwi 0,d1,0
+ beq copy_array_21_b
+
+ cmpw 0,d0,d1
+ beq copy_array_21_r_a
+
+copy_array_21_ab:
+ subic. d5,d5,1
+ blt copy_lp1
+
+ sub d0,d0,d1
+ slwi d0,d0,2
+ subi d1,d1,1
+
+ mr d6,d5
+ stw d1,-4(sp)
+ stwu d0,-8(sp)
+
+copy_array_21_lp_ab:
+ lwz d5,4(sp)
+ bl copy_lp2
+
+ lwz o1,0(sp)
+ subic. d6,d6,1
+ add a2,a2,o1
+ bge copy_array_21_lp_ab
+
+ baddi sp,8
+ b copy_lp1
+
+copy_array_21_b:
+ mullw d2,d5,d0
+ slwi d2,d2,2
+ add a2,a2,d2
+ b copy_lp1
+
+copy_array_21_r_a:
+ mullw d2,d5,d0
+ mr d5,d2
+copy_array_21_a:
+ subic. d5,d5,1
+ bge copy_lp2
+
+ b copy_lp1
+
+;
+; Copy root nodes to the other semi-space
+;
+
+b_copy_lp2:
+ bsubi d5,1
+copy_lp2:
+ lwz a1,0(a2)
+ baddi a2,4
+
+ lwz d0,0-NODE_POINTER_OFFSET(a1)
+ bsubi d5,1
+
+continue_after_selector_2:
+ andi. r0,d0,2
+ beq not_in_hnf_2
+
+in_hnf_2: lhz d2,-2(d0)
+ cmpwi 5,d5,0
+
+ cmpwi 0,d2,0
+ beq copy_arity_0_node2
+
+ cmplwi 6,d2,256
+ if NODE_POINTER_OFFSET==0
+ stw a6,-4(a2)
+ endif
+ stw d0,0(a6)
+ bge 6,copy_record_2
+
+ subic. d2,d2,2
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+
+ addi a0,a6,1+NODE_POINTER_OFFSET
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+
+ blt copy_hnf_node2_1
+ bgt copy_hnf_node2_3
+
+ lwz o1,8-NODE_POINTER_OFFSET(a1)
+
+ stw o0,4(a6)
+ if NODE_POINTER_OFFSET==0
+ stw o1,8(a6)
+ stw a6,-4(a2)
+ baddi a6,12
+ else
+ stwu o1,8(a6)
+ stw a6,-4(a2)
+ baddi a6,4
+ endif
+ bge 5,copy_lp2
+ blr
+
+copy_hnf_node2_1:
+ stw o0,4(a6)
+ baddi a6,8
+ if NODE_POINTER_OFFSET
+ stw a6,-4(a2)
+ endif
+ bge 5,copy_lp2
+ blr
+
+copy_hnf_node2_3:
+ lwz a0,8-NODE_POINTER_OFFSET(a1)
+ baddi a6,12
+
+ stw o0,4-12(a6)
+ if NODE_POINTER_OFFSET
+ addi a1,a6,NODE_POINTER_OFFSET
+ endif
+ lwz d1,0-NODE_POINTER_OFFSET(a0)
+
+ andi. r0,d1,1
+ bne arguments_already_copied_2
+
+ if NODE_POINTER_OFFSET==0
+ stw a6,-4(a6)
+ ori a1,a6,1
+ stw d1,0(a6)
+ else
+ stwu a1,-4(a6)
+ ori a1,a1,1
+ stw a6,-4(a2)
+ stwu d1,4(a6)
+ endif
+ stw a1,0-NODE_POINTER_OFFSET(a0)
+
+cp_hnf_arg_lp2:
+ if NODE_POINTER_OFFSET
+ lwz o0,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,4
+ else
+ lwzu o0,4(a0)
+ endif
+ subic. d2,d2,1
+ stwu o0,4(a6)
+ bgt cp_hnf_arg_lp2
+
+ baddi a6,4
+
+ bge 5,copy_lp2
+ blr
+
+arguments_already_copied_2:
+ stw d1,-4(a6)
+ if NODE_POINTER_OFFSET
+ addi a1,a6,-4
+ stw a1,-4(a2)
+ endif
+ bge 5,copy_lp2
+ blr
+
+copy_arity_0_node2:
+ cmplw d0,int_reg
+ blt copy_real_file_or_string_2
+
+ cmplw d0,char_reg
+ bgt copy_normal_hnf_0_2
+
+copy_int_bool_or_char_2:
+ if SHARE_CHAR_INT
+ bne no_char_2
+
+ lbz d2,7-NODE_POINTER_OFFSET(a1)
+ if NODE_POINTER_OFFSET
+ lea a0,static_characters8
+ else
+ lea a0,static_characters
+ endif
+ slwi d2,d2,3
+ add a0,a0,d2
+ stw a0,-4(a2)
+
+ bge 5,copy_lp2
+ blr
+
+no_char_2:
+ cmpw int_reg,d0
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+ bne no_small_int_or_char_2
+
+ cmplwi 0,o0,33
+ slwi d2,o0,3
+ bge no_small_int_or_char_2
+
+ if NODE_POINTER_OFFSET
+ lea a0,small_integers8
+ else
+ lea a0,small_integers
+ endif
+ add a0,a0,d2
+ stw a0,-4(a2)
+
+ bge 5,copy_lp2
+ blr
+
+no_small_int_or_char_2:
+ else
+no_small_int_or_char_2:
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+ endif
+
+ if NODE_POINTER_OFFSET
+ ori d2,o4,1
+ stw o4,-4(a2)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ endif
+
+ stwu d0,-8(o4)
+ stw o0,4(o4)
+
+ if NODE_POINTER_OFFSET==0
+ ori d2,o4,1
+ stw o4,-4(a2)
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ endif
+
+ bge 5,copy_lp2
+ blr
+
+copy_normal_hnf_0_2:
+ subi a0,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET-NODE_POINTER_OFFSET
+ stw a0,-4(a2)
+ bge 5,copy_lp2
+ blr
+
+copy_real_file_or_string_2:
+ lea o0,__STRING__2
+ cmplw 0,d0,o0
+ ble copy_string_or_array_2
+
+copy_real_or_file_2:
+ if NODE_POINTER_OFFSET==0
+ stwu d0,-12(o4)
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+
+ addi d2,o4,1
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+
+ lwz o1,8-NODE_POINTER_OFFSET(a1)
+
+ stw o0,4(o4)
+ stw o1,8(o4)
+ stw o4,-4(a2)
+ else
+ lwz o1,8-NODE_POINTER_OFFSET(a1)
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+ stwu o1,-4(o4)
+ stw o4,-4(a2)
+ addi d2,o4,1
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ stw o0,-4(o4)
+ stwu d0,-8(o4)
+ endif
+ bge 5,copy_lp2
+ blr
+
+already_copied_2:
+ cmpwi 5,d5,0
+already_copied_2_:
+ subi d0,d0,1
+ stw d0,-4(a2)
+
+ bge 5,copy_lp2
+ blr
+
+; to do: copy strict basic records to end of heap
+
+copy_record_2:
+ subic. d2,d2,258
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+
+ addi a0,a6,1+NODE_POINTER_OFFSET
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+
+ blt copy_record_node2_1
+ bgt copy_record_node2_3
+
+ lwz o1,8-NODE_POINTER_OFFSET(a1)
+
+ stw o0,4(a6)
+ if NODE_POINTER_OFFSET==0
+ stw o1,8(a6)
+ baddi a6,12
+ else
+ stwu o1,8(a6)
+ stw a6,-4(a2)
+ baddi a6,4
+ endif
+ bge 5,copy_lp2
+ blr
+
+copy_record_node2_1:
+ stw o0,4-NODE_POINTER_OFFSET(a6)
+ baddi a6,8
+ if NODE_POINTER_OFFSET
+ stw a6,-4(a2)
+ endif
+ bge 5,copy_lp2
+ blr
+
+copy_record_node2_3:
+ lwz a0,8-NODE_POINTER_OFFSET(a1)
+ stw o0,4(a6)
+
+ if COPIED_VECTOR
+ lea a1,heap_copied_vector
+ sub d0,a0,a3
+ lwz a1,0(a1)
+
+ tstmbit a1,d0,d1,o0,o1,o2,3
+ bne record_arguments_already_copied_2
+
+ li o0,128
+ srw o0,o0,o2
+ or o1,o1,o0
+ stbx o1,a1,d1
+ endif
+ if NODE_POINTER_OFFSET==0
+ addi a1,a6,12
+ stw a1,8(a6)
+ else
+ addi a1,a6,12+NODE_POINTER_OFFSET
+ stwu a1,8(a6)
+ stw a6,-4(a2)
+ endif
+ lwz o1,0-NODE_POINTER_OFFSET(a0)
+ addi a1,a1,1
+ stw a1,0-NODE_POINTER_OFFSET(a0)
+ if NODE_POINTER_OFFSET==0
+ stwu o1,12(a6)
+ else
+ stwu o1,4(a6)
+ endif
+ subi d2,d2,1
+
+cp_record_arg_lp2:
+ if NODE_POINTER_OFFSET
+ lwz o1,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,4
+ else
+ lwzu o1,4(a0)
+ endif
+ subic. d2,d2,1
+ stwu o1,4(a6)
+ bge cp_record_arg_lp2
+
+ addi a6,a6,4
+
+ bge 5,copy_lp2
+ blr
+
+ if COPIED_VECTOR
+record_arguments_already_copied_2:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ if NODE_POINTER_OFFSET==0
+ addi a6,a6,12
+
+ stw o0,-4(a6)
+ else
+ stwu o0,8(a6)
+ stw a6,-4(a2)
+ addi a6,a6,4
+ endif
+ bge 5,copy_lp2
+ blr
+ endif
+
+not_in_hnf_2:
+ andi. r0,d0,1
+ bne- already_copied_2
+
+ lwz d2,-4-NODE_POINTER_OFFSET(d0)
+ cmpwi 5,d5,0
+
+ extsb. d2,d2
+ beq copy_arity_0_node2_
+
+copy_node2_1_:
+ subic. d2,d2,2
+ blt copy_arity_1_node2
+
+copy_node2_3:
+ if NODE_POINTER_OFFSET==0
+ stw a6,-4(a2)
+ endif
+ stw d0,0(a6)
+ addi a0,a6,1+NODE_POINTER_OFFSET
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ lwzu o0,4-NODE_POINTER_OFFSET(a1)
+ if NODE_POINTER_OFFSET
+ addi o1,a6,8
+ stw o1,-4(a2)
+ endif
+ stwu o0,4(a6)
+cp_arg_lp2:
+ lwzu o0,4(a1)
+ subic. d2,d2,1
+ stwu o0,4(a6)
+ bge cp_arg_lp2
+
+ addi a6,a6,4
+ bge 5,copy_lp2
+ blr
+
+copy_arity_1_node2:
+ cmpwi 0,d2,-1-2
+ ble copy_selector_2
+
+copy_arity_1_node2_:
+ if NODE_POINTER_OFFSET==0
+ stw a6,-4(a2)
+ endif
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+ addi a0,a6,1+NODE_POINTER_OFFSET
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ if NODE_POINTER_OFFSET
+ addi o1,a6,8
+ stw o1,-4(a2)
+ endif
+ stw d0,0(a6)
+ stw o0,4(a6)
+ addi a6,a6,12
+
+ bge 5,copy_lp2
+ blr
+
+copy_indirection_2:
+ mr d1,a1
+ lwz a1,4-NODE_POINTER_OFFSET(a1)
+
+ lwz d0,0-NODE_POINTER_OFFSET(a1)
+
+ andi. r0,d0,2
+ bne in_hnf_2
+
+ andi. r0,d0,1
+ bne already_copied_2_
+
+ lwz d2,-4(d0)
+
+ extsb. d2,d2
+ beq copy_arity_0_node2_
+
+ cmpwi 0,d2,-2
+ bne copy_node2_1_
+
+skip_indirections_2:
+ lwz a1,4-NODE_POINTER_OFFSET(a1)
+ lwz d0,0-NODE_POINTER_OFFSET(a1)
+
+ andi. r0,d0,3
+ bne update_indirection_list_2
+
+ lwz o0,-4(d0)
+ mr a0,d0
+ cmpwi 0,o0,-2
+ beq skip_indirections_2
+
+update_indirection_list_2:
+ addi a0,d1,4
+ lwz d1,0-NODE_POINTER_OFFSET(a0)
+ stw a1,0-NODE_POINTER_OFFSET(a0)
+ cmpw 0,a1,d1
+ bne update_indirection_list_2
+
+ lwz d0,0-NODE_POINTER_OFFSET(a1)
+ b continue_after_selector_2
+
+copy_selector_2:
+ cmpwi 0,d2,-2-2
+ beq copy_indirection_2
+
+ mr a0,d0
+
+; if no selectors
+; b copy_arity_1_node2_
+
+ blt copy_record_selector_2
+
+ if LINUX
+ lwz d2,-8(a0)
+ else
+ lha d2,-6(a0)
+ endif
+ lwz a0,4-NODE_POINTER_OFFSET(a1)
+ lwz d1,0-NODE_POINTER_OFFSET(a0)
+ andi. r0,d1,2
+ beq copy_arity_1_node2_
+
+ lha g1,-2(d1)
+ cmplwi 0,g1,2
+ ble copy_selector_2_
+
+ lwz g1,8-NODE_POINTER_OFFSET(a0)
+ lwz g1,0-NODE_POINTER_OFFSET(g1)
+ andi. r0,g1,1
+ bne copy_arity_1_node2_
+
+copy_selector_2_:
+ if LINUX
+ else
+ lwzx d2,rtoc,d2
+ endif
+ lwz g1,4(d2)
+
+ mtctr g1
+
+ mr d2,a1
+
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+
+ mr a1,a0
+ lwz d0,0-NODE_POINTER_OFFSET(a1)
+ b continue_after_selector_2
+
+copy_record_selector_2:
+ cmpwi 0,d2,-2-3
+ if LINUX
+ lwz d2,-8(a0)
+ else
+ lha d2,-6(a0)
+ endif
+ beq copy_strict_record_selector_2
+
+ lwz a0,4-NODE_POINTER_OFFSET(a1)
+ lwz d1,0-NODE_POINTER_OFFSET(a0)
+ andi. r0,d1,2
+ beq copy_arity_1_node2_
+
+ lha g1,-2(d1)
+ cmplwi 0,g1,258
+ ble copy_selector_2_
+
+ if COPIED_VECTOR
+ lea g1,heap_copied_vector
+ lwz g0,8-NODE_POINTER_OFFSET(a0)
+ lwz g1,0(g1)
+ sub g0,g0,a3
+
+ tstmbit g1,g0,d1,o0,o1,o2,3
+ bne copy_arity_1_node2_
+ endif
+ b copy_selector_2_
+
+copy_strict_record_selector_2:
+ lwz a0,4-NODE_POINTER_OFFSET(a1)
+ lwz d1,0-NODE_POINTER_OFFSET(a0)
+ andi. r0,d1,2
+ beq copy_arity_1_node2_
+
+ lha g1,-2(d1)
+ cmplwi 0,g1,258
+ ble copy_strict_record_selector_2_
+
+ if COPIED_VECTOR
+ lea g1,heap_copied_vector
+ lwz g0,8-NODE_POINTER_OFFSET(a0)
+ lwz g1,0(g1)
+ sub g0,g0,a3
+
+ tstmbit g1,g0,d1,o0,o1,o2,3
+ bne copy_arity_1_node2_
+ endif
+
+copy_strict_record_selector_2_:
+ if LINUX
+ else
+ lwzx d2,rtoc,d2
+ endif
+ mr d0,a1
+ lwz g1,4(d2)
+ mr a1,a0
+ mtctr g1
+
+ mr a0,d0
+
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+ mr a1,a0
+ b in_hnf_2
+
+copy_arity_0_node2_:
+ if NODE_POINTER_OFFSET==0
+ stwu d0,-12(o4)
+ stw o4,-4(a2)
+ ori d2,o4,1
+ else
+ addi o1,o4,-4
+ stwu d0,-12(o4)
+ ori d2,o1,1
+ stw o1,-4(a2)
+ endif
+ stw d2,0-NODE_POINTER_OFFSET(a1)
+ bge 5,copy_lp2
+ blr
+
+copy_string_or_array_2:
+ bne copy_array_2
+
+ sub d1,a1,a3
+ cmplw 0,d1,d7
+ bge copy_string_constant
+
+ lwz d2,4-NODE_POINTER_OFFSET(a1)
+ mr a0,a1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ addi d2,d2,3
+ srwi d2,d2,2
+
+ slwi d1,d2,2
+ subi a1,o4,8-NODE_POINTER_OFFSET
+ sub a1,a1,d1
+
+ stw a1,-4(a2)
+ ori d0,a1,1
+
+ subi o4,a1,NODE_POINTER_OFFSET
+ if NODE_POINTER_OFFSET
+ stwu d0,0-NODE_POINTER_OFFSET(a0)
+ stwu o0,0-NODE_POINTER_OFFSET(a1)
+ else
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ stw o0,0(a1)
+ endif
+
+cp_s_arg_lp2:
+ lwzu o0,4(a0)
+ subic. d2,d2,1
+ stwu o0,4(a1)
+ bge cp_s_arg_lp2
+
+ bge 5,copy_lp2
+ blr
+
+copy_string_constant:
+ stw a1,-4(a2)
+ bge 5,copy_lp2
+ blr
+
+copy_array_2:
+ mr a0,a1
+
+ lwz d0,8-NODE_POINTER_OFFSET(a0)
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ cmpwi 0,d0,0
+ beq copy_array_a2
+
+ lhz d1,-2(d0)
+ cmpwi 0,d1,0
+ beq copy_strict_basic_array_2
+
+ subi d0,d1,256
+ mullw d2,d2,d0
+
+copy_array_a2:
+ addi a1,a6,-NODE_POINTER_OFFSET
+
+ slwi d1,d2,2
+ add a6,a6,d1
+ addi a6,a6,12
+
+ stw a1,-4(a2)
+ addi d0,a1,1
+
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ if NODE_POINTER_OFFSET
+ stwu d0,0-NODE_POINTER_OFFSET(a0)
+ addi d2,d2,1
+ stwu o0,0-NODE_POINTER_OFFSET(a1)
+ else
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ addi d2,d2,1
+ stw o0,0(a1)
+ endif
+ b cp_s_arg_lp2
+
+copy_strict_basic_array_2:
+ cmplw d0,int_reg
+ beq copy_int_array_2
+ cmpw bool_reg,d0
+ beq copy_bool_array_2
+ add d2,d2,d2
+copy_int_array_2:
+ slwi d1,d2,2
+ subi a1,o4,12-NODE_POINTER_OFFSET
+
+ sub a1,a1,d1
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+
+ stw a1,-4(a2)
+ addi d0,a1,1
+
+ subi o4,a1,NODE_POINTER_OFFSET
+ if NODE_POINTER_OFFSET
+ stwu d0,0-NODE_POINTER_OFFSET(a0)
+ addi d2,d2,1
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ else
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+ addi d2,d2,1
+ stw o0,0(a1)
+ endif
+ b cp_s_arg_lp2
+
+copy_bool_array_2:
+ addi d2,d2,3
+ srwi d2,d2,2
+ b copy_int_array_2
+
+end_copy1:
+
+ if FINALIZERS
+ lea a0,finalizer_list
+ lea a1,free_finalizer_list
+ lwz a2,0(a0)
+
+determine_free_finalizers_after_copy:
+ lwz d0,0(a2)
+ andi. o0,d0,1
+ beq finalizer_not_used_after_copy
+
+ lwz a2,4(a2)
+ subi d0,d0,1
+ stw d0,0(a0)
+ addi a0,d0,4
+ b determine_free_finalizers_after_copy
+
+finalizer_not_used_after_copy:
+ lea o0,__Nil_m8
+ cmplw a2,o0
+ beq end_finalizers_after_copy
+
+ stw a2,0(a1)
+ addi a1,a2,4
+ lwz a2,4(a2)
+ b determine_free_finalizers_after_copy
+
+end_finalizers_after_copy:
+ stw a2,0(a0)
+ stw a2,0(a1)
+ endif
diff --git a/pfileIO3.a b/pfileIO3.a
new file mode 100644
index 0000000..8bf0571
--- /dev/null
+++ b/pfileIO3.a
@@ -0,0 +1,1428 @@
+; File: pfileIO3.s
+; Copyright: University of Nijmegen
+; Written by: John van Groningen
+; Machine: Power Macintosh
+
+ string asis
+
+MACOSX set 1
+
+d0: set r24
+d1: set r25
+d2: set r26
+d3: set r27
+d4: set r28
+d5: set r29
+d6: set r30
+d7: set r31
+a0: set r23
+a1: set r22
+a2: set r21
+a3: set r20
+a4: set r19
+a5: set r18
+a6: set r17
+
+o0: set r3
+o1: set r4
+o2: set r5
+o3: set r6
+o4: set r7
+o5: set r8
+
+g0: set r11
+g1: set r12
+g2: set r13
+g3: set r14
+g4: set r15
+g5: set r16
+
+ include 'pmacros.a'
+
+ csect data{RW}
+ align 3
+tmp_real: dc.d "0.0"
+freadstring_error:
+ dc.b 'Error in freadsubstring parameters.'
+ dc.b 13,0
+ dc.b 0,0,0
+fwritestring_error:
+ dc.b 'Error in fwritesubstring parameters.'
+ dc.b 13,0
+ dc.b 0,0
+
+ csect text{PR}
+
+ export stdioF
+ export stderrF
+ export openF
+ export closeF
+ export reopenF
+ export readFC
+ export readFI
+ export readFR
+ export readFS
+ export readFString
+ export readLineF
+ export writeFC
+ export writeFI
+ export writeFR
+ export writeFS
+ export writeFString
+ export __endF=>'endF'
+ export errorF
+ export positionF
+ export seekF
+ export shareF
+
+ export openSF
+ export readSFC
+ export readSFI
+ export readSFR
+ export readSFS
+ export readLineSF
+ export endSF
+ export positionSF
+ export seekSF
+
+ import collect_0
+ import collect_1
+ import __STRING__
+
+ csect .stdioF{PR}
+ import .open_stdio
+stdioF: mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .open_stdio
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d1,r3
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .stderrF{PR}
+ import .open_stderr
+stderrF: mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .open_stderr
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d1,r3
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .openF{PR}
+ import .open_file
+openF: mr o1,d0
+ addi o0,a0,4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .open_file
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d1,o0,0
+ li d0,-1
+ blt openF_1
+ li d2,-1
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+openF_1:
+ li d2,0
+ lwz r0,0(sp)
+ neg d1,d1
+ addi sp,sp,4
+ blr
+
+ csect .closeF{PR}
+ import .close_file
+closeF: mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .close_file
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d0,o0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .reopenF{PR}
+ import .re_open_file
+reopenF:
+ mr o0,d2
+ mr o1,d0
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .re_open_file
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d1,d2
+ mr d2,o0
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .readFC{PR}
+ import .file_read_char
+readFC:
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_char
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ cmpwi 0,o0,-1
+ li d0,-1
+ beq readFC_eof
+
+ li d3,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+readFC_eof:
+ li d2,0
+ li d3,0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .readFI{PR}
+ import .file_read_int
+readFI:
+ subi sp,sp,4
+ mr o1,sp
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_int
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ lwz d2,0(sp)
+ li d0,-1
+ mr d3,o0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ csect .readFR{PR}
+ import .file_read_real
+readFR:
+ lea o1,tmp_real
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_real
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ lea o1,tmp_real
+ mr d2,o0
+ lfd f14,0(o1)
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+
+
+
+
+ csect .readFString{PR}
+ import .file_read_characters
+ import print_error
+readFString:
+ lwz d4,4(a0)
+ cmplw 0,d3,d4
+ bge readFString_error
+
+ sub o0,d4,d3
+ cmplw 0,d2,o0
+ bgt readFString_error
+
+ addi o2,a0,8
+ stwu d2,-4(sp)
+ add o2,o2,d3
+ mr o1,sp
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_characters
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ li d0,-1
+
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+readFString_error:
+ lea o0,freadstring_error
+ b print_error
+
+ csect .readFS{PR}
+ if 0
+ import .file_read_string
+ else
+ import .file_read_characters
+ endif
+readFS:
+ addi d5,d0,8+3
+ srwi d5,d5,2
+ sub. d7,d7,d5
+ blt readFS_gc
+readFS_r_gc:
+ add d7,d7,d5
+ mr d4,d2
+
+ lea o0,__STRING__2
+ addi d3,a6,4
+ stwu o0,4(a6)
+ if 0
+ addi o2,a6,4
+ mr o1,d0
+ else
+ addi o2,a6,8
+ stw d0,4(a6)
+ addi o1,a6,4
+ endif
+ mr o0,d2
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ if 0
+ bl .file_read_string
+ else
+ bl .file_read_characters
+ endif
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+readFS_end:
+ addi d0,o0,3
+ clrrwi d0,d0,2
+ addi a6,a6,4
+ add a6,a6,d0
+ srwi d0,d0,2
+ baddi d0,2
+ bsub d7,d0
+
+ mr a0,d3
+ mr d1,d4
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+readFS_gc:
+ mflr r0
+ bl collect_0
+ b readFS_r_gc
+
+ csect .readLineF{PR}
+ import .file_read_line
+readLineF:
+ li d5,32+2
+ cmpw 0,d7,d5
+ blt readLineF_gc
+
+readLineF_r_gc:
+ mr d4,d1
+
+ lea o0,__STRING__2
+ addi d3,a6,4
+ stwu o0,4(a6)
+
+ addi o2,a6,8
+ subi o1,d7,2
+ slwi o1,o1,2
+ mr o0,d4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_line
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d0,o0,0
+ stw d0,4(a6)
+ bge readFS_end
+
+ subi d0,d7,2
+ slwi d0,d0,2
+ stwu d0,4(a6)
+
+readLineF_lp:
+ add a6,a6,d0
+
+ lwz d5,4(d3)
+ mr a0,d3
+ srwi d5,d5,2
+ addi d5,d5,2+32
+ neg d7,d5
+
+ mflr r0
+ bl collect_1
+
+ mr a1,a0
+ add d7,d7,d5
+ lwzu d0,4(a1)
+ addi d1,d0,3
+ srwi d1,d1,2
+ subi d7,d7,2
+ sub d7,d7,d1
+
+ lea o0,__STRING__2
+ subic. d1,d1,1
+
+ addi d3,a6,4
+ stw o0,4(a6)
+ stwu d0,8(a6)
+ blt end_copy_string1
+
+copy_st_lp1:
+ lwzu g1,4(a1)
+ subic. d1,d1,1
+ stwu g1,4(a6)
+ bge copy_st_lp1
+end_copy_string1:
+
+ addi o2,a6,4
+ slwi o1,d7,2
+ mr o0,d4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_line
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d0,o0,0
+ lwz g1,4(d3)
+ blt readLineF_again
+
+ mr a0,d3
+ add g1,g1,d0
+ stw g1,4(d3)
+
+ addi d1,d0,3
+ srwi d1,d1,2
+ sub d7,d7,d1
+ slwi d1,d1,2
+ add a6,a6,d1
+
+ mr d1,d4
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+readLineF_gc:
+ sub d7,d7,d5
+ mflr r0
+ bl collect_0
+ add d7,d7,d5
+ b readLineF_r_gc
+
+readLineF_again:
+ slwi d0,d7,2
+ add g1,g1,d0
+ stw g1,4(d3)
+ b readLineF_lp
+
+ csect .writeFC{PR}
+ import .file_write_char
+writeFC:
+ mr o1,d1
+ mr o0,d2
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_write_char
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .writeFI{PR}
+ import .file_write_int
+writeFI:
+ mr o1,d1
+ mr o0,d2
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_write_int
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .writeFR{PR}
+ import .file_write_real
+writeFR:
+ mr o2,d1
+ fmr f1,f14
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_write_real
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .writeFS{PR}
+ if 0
+ import .file_write_string
+ else
+ import .file_write_characters
+ endif
+writeFS:
+ if 0
+ mr o1,d1
+ addi o0,a0,4
+ else
+ lwz o1,4(a0)
+ mr o2,d1
+ addi o0,a0,8
+ endif
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ if 0
+ bl .file_write_string
+ else
+ bl .file_write_characters
+ endif
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ if 1
+ csect .writeFString{PR}
+ import .file_write_characters
+ import print_error
+writeFString:
+ lwz d4,4(a0)
+ cmplw 0,d3,d4
+ bge writeFString_error
+
+ sub o0,d4,d3
+ cmplw 0,d2,o0
+ bgt writeFString_error
+
+ mr o2,d1
+ addi o0,a0,8
+ mr o1,d2
+ add o0,o0,d3
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_write_characters
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+writeFString_error:
+ lea o0,fwritestring_error
+ b print_error
+ endif
+
+ csect .__endF{PR}
+ import .file_end
+__endF:
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_end
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+ mr d2,o0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .errorF{PR}
+ import .file_error
+errorF:
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_error
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .positionF{PR}
+ import .file_position
+positionF:
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_position
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .seekF{PR}
+ import .file_seek
+seekF:
+ mr o2,d0
+ mr o1,d1
+ mr o0,d3
+ mr d1,d3
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_seek
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .shareF{PR}
+ import .file_share
+shareF:
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_share
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .openSF{PR}
+ import .open_s_file
+openSF:
+ mr o1,d0
+ addi o0,a0,4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .open_s_file
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d1,o0,0
+ li d0,0
+ blt openSF_1
+ li d2,-1
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+openSF_1:
+ li d2,0
+ lwz r0,0(sp)
+ neg d1,d1
+ addi sp,sp,4
+ blr
+
+ csect .readSFC{PR}
+ import .file_read_s_char
+readSFC:
+ stwu d0,-4(sp)
+ mr o1,sp
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_char
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d2,o0
+ cmpwi 0,o0,-1
+ lwz d0,0(sp)
+ beq readSFC_eof
+
+ li d3,-1
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+readSFC_eof:
+ li d2,0
+ li d3,0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ csect .readSFI{PR}
+ import .file_read_s_int
+readSFI:
+ stwu d0,-4(sp)
+ mr o2,sp
+ subi sp,sp,4
+ mr o1,sp
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_int
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ lwz d2,0(sp)
+ lwz d0,4(sp)
+ mr d3,o0
+
+ lwz r0,8(sp)
+ addi sp,sp,12
+ blr
+
+ csect .readSFR{PR}
+ import .file_read_s_real
+readSFR:
+ stwu d0,-4(sp)
+ mr o2,sp
+ lea o1,tmp_real
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_real
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ lea g1,tmp_real
+ lwz d0,0(sp)
+ lfd f14,0(g1)
+ mr d2,o0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ csect .readSFS{PR}
+ import .file_read_s_string
+readSFS:
+ addi d5,d0,8+3
+ srwi d5,d5,2
+ sub. d7,d7,d5
+ blt readSFS_gc
+readSFS_r_gc:
+ add d7,d7,d5
+ mr d4,d2
+
+ lea o0,__STRING__2
+ addi d3,a6,4
+ stwu o0,4(a6)
+
+ stwu d1,-4(sp)
+ mr o3,sp
+ addi o2,a6,4
+ mr o1,d0
+ mr o0,d2
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_string
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+readSFS_end:
+ addi d0,d0,3
+ clrrwi d0,d0,2
+ addi a6,a6,4
+ add a6,a6,d0
+ srwi d0,d0,2
+ baddi d0,2
+ bsub d7,d0
+
+ mr a0,d3
+ mr d1,d4
+ lwz d0,0(sp)
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+readSFS_gc:
+ mflr r0
+ bl collect_0
+ b readSFS_r_gc
+
+ csect .readLineSF{PR}
+ import .file_read_s_line
+readLineSF:
+ li d5,32+2
+ cmpw 0,d7,d5
+ blt readLineSF_gc
+
+readLineSF_r_gc:
+ stwu d0,-4(sp)
+ mr d4,d1
+
+ lea o0,__STRING__2
+ addi d3,a6,4
+ stwu o0,4(a6)
+
+ mr o3,sp
+ addi o2,a6,8
+ subi o1,d7,2
+ slwi o1,o1,2
+ mr o0,d4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_line
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d0,o0,0
+ stw d0,4(a6)
+ bge readSFS_end
+
+ subi d0,d7,2
+ slwi d0,d0,2
+ stwu d0,4(a6)
+
+readLineSF_lp:
+ add a6,a6,d0
+
+ lwz d5,4(d3)
+ mr a0,d3
+ srwi d5,d5,2
+ addi d5,d5,2+32
+ neg d7,d5
+
+ mflr r0
+ bl collect_1
+
+ mr a1,a0
+ add d7,d7,d5
+ lwzu d0,4(a1)
+ addi d1,d0,3
+ srwi d1,d1,2
+ subi d7,d7,2
+ sub d7,d7,d1
+
+ lea o0,__STRING__2
+ subic. d1,d1,1
+
+ addi d3,a6,4
+ stw o0,4(a6)
+ stwu d0,8(a6)
+ blt end_copy_string2
+
+copy_st_lp2:
+ lwzu g1,4(a1)
+ subic. d1,d1,1
+ stwu g1,4(a6)
+ bge copy_st_lp2
+end_copy_string2:
+
+ mr o3,sp
+ addi o2,a6,4
+ slwi o1,d7,2
+ mr o0,d4
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_read_s_line
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ addic. d0,o0,0
+ lwz g1,4(d3)
+ blt readLineSF_again
+
+ mr a0,d3
+ add g1,g1,d0
+ stw g1,4(d3)
+
+ addi d1,d0,3
+ srwi d1,d1,2
+ sub d7,d7,d1
+ slwi d1,d1,2
+ add a6,a6,d1
+
+ lwz d0,0(sp)
+ mr d1,d4
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+readLineSF_gc:
+ sub d7,d7,d5
+ mflr r0
+ bl collect_0
+ add d7,d7,d5
+ b readLineSF_r_gc
+
+readLineSF_again:
+ slwi d0,d7,2
+ add g1,g1,d0
+ stw g1,4(d3)
+ b readLineSF_lp
+
+ csect .endSF{PR}
+ import .file_s_end
+endSF:
+ mr o1,d0
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_s_end
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d0,o0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .positionSF{PR}
+ import .file_s_position
+positionSF:
+ mr o1,d0
+ mr o0,d1
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_s_position
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ mr d0,o0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .seekSF{PR}
+ import .file_s_seek
+seekSF:
+ stwu d2,-4(sp)
+ mr o3,sp
+
+ mr o2,d0
+ mr o1,d1
+ mr o0,d3
+ mr d1,d3
+
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ stw r0,60(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .file_s_seek
+ lwz r0,60(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ lwz d0,0(sp)
+ mr d2,o0
+
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ macro
+ te &address
+ tc &address{TC},&address
+ endm
+
+ toc
+
+ te tmp_real
+ te freadstring_error
+ te fwritestring_error
+ tc __STRING__2{TC},__STRING__+2
diff --git a/pmacros.a b/pmacros.a
new file mode 100644
index 0000000..f18e8af
--- /dev/null
+++ b/pmacros.a
@@ -0,0 +1,54 @@
+ macro
+ lea &r,&a
+ lwz &r,&a{TC}(RTOC)
+ endm
+
+ macro
+ tst &r
+ cmpwi 0,&r,0
+ endm
+
+ macro
+ badd &rd,&rs
+ add &rd,&rd,&rs
+ endm
+
+ macro
+ baddi &rd,&i
+ addi &rd,&rd,&i
+ endm
+
+ macro
+ baddicc &r,&i
+ addic. &r,&r,&i
+ endm
+
+ macro
+ bandic &r,&i
+ andi. &r,&r,&i
+ endm
+
+ macro
+ bsub &rd,&rs
+ sub &rd,&rd,&rs
+ endm
+
+ macro
+ bsubc &rd,&rs
+ sub. &rd,&rd,&rs
+ endm
+
+ macro
+ bsubi &r,&i
+ subi &r,&r,&i
+ endm
+
+ macro
+ bsubicc &r,&i
+ subic. &r,&r,&i
+ endm
+
+ macro
+ bor &rd,&rs
+ or &rd,&rd,&rs
+ endm
diff --git a/pmark.a b/pmark.a
new file mode 100644
index 0000000..99272cd
--- /dev/null
+++ b/pmark.a
@@ -0,0 +1,2316 @@
+
+COUNT_GARBAGE_COLLECTIONS set 0
+MARK_USING_REVERSAL set 0
+REMOVE_INDIRECTION_LISTS set 0
+
+ if 0
+ subi sp,sp,256
+ stmw r3,68(sp)
+ mflr r3
+ stw r3,64(sp)
+ bl .Debugger
+ nop
+ lwz r3,64(sp)
+ mtlr r3
+ lmw r3,68(sp)
+ baddi sp,256
+ endif
+
+ lea d7,heap_size_33
+ lea o0,lazy_array_list
+ lwz d7,0(d7)
+ li d4,0
+ stw d4,0(o0)
+
+ lis g3,32768
+
+ subi a3,sp,2000
+
+ lea d0,caf_list
+ slwi d7,d7,5
+ lwz d0,0(d0)
+
+ stwu a4,-4(sp)
+
+ tst d0
+ beq _end_mark_cafs
+
+_mark_cafs_lp:
+ lwz d1,0(d0)
+ lwz o5,-4(d0)
+ addi a2,d0,4
+ slwi d0,d1,2
+ add a4,a2,d0
+ bl _mark_stack_nodes
+
+ addic. d0,o5,0
+ bne _mark_cafs_lp
+
+_end_mark_cafs:
+ lea a2,stack_p
+ lwz a4,0(sp)
+ lwz a2,0(a2)
+ baddi sp,4
+
+ bl _mark_stack_nodes
+
+ lea a0,lazy_array_list
+ lwz a0,0(a0)
+
+ tst a0
+ beq end_restore_arrays
+
+restore_arrays:
+ lwz d3,0(a0) ; size
+ lwz d1,4(a0) ; second last element
+ cmplwi 0,d3,1
+
+ lea o0,__ARRAY__2
+ lwz d2,8(a0) ; last element
+ stw o0,0(a0)
+ beq restore_array_size_1
+
+ slwi a1,d3,2
+ add a1,a0,a1
+
+ lwz d0,8(a1) ; descriptor
+
+ tst d0
+ beq restore_lazy_array
+
+ lhz o0,-2+2(d0)
+ divwu d3,d3,o0
+
+restore_lazy_array:
+ stw d3,4(a0)
+ lwz a3,4(a1) ; next
+ stw d0,8(a0)
+
+ stw d1,4(a1)
+ stw d2,8(a1)
+
+ tst d0
+ beq no_reorder_array
+
+ lhz o1,-2(d0)
+ subi o1,o1,256
+ cmpw 0,o1,o0
+ beq no_reorder_array
+
+ mr d0,o1
+ mr d1,o0
+ slwi d3,d3,2
+ mullw d3,d3,d0
+ baddi a0,12
+ add a1,a0,d3
+ sub d0,d0,d1
+
+ mr g1,d4
+
+ bl reorder
+
+ mr d4,g1
+
+no_reorder_array:
+ addic. a0,a3,0
+ bne restore_arrays
+
+ b end_restore_arrays
+
+restore_array_size_1:
+ stw d3,4(a0)
+ lwz a3,12(a0) ; descriptor
+
+ stw d1,12(a0)
+ stw a3,8(a0)
+
+ addic. a0,d2,0
+ bne restore_arrays
+
+end_restore_arrays:
+
+ if FINALIZERS
+ lea a0,finalizer_list
+ lea a1,free_finalizer_list
+
+ lwz a2,0(a0)
+determine_free_finalizers_after_mark:
+ lea o0,__Nil_m8
+ cmplw o0,a2
+ beq end_finalizers_after_mark
+
+ sub d1,a2,d6
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ beq finalizer_not_used_after_mark
+
+ addi a0,a2,4
+ lwz a2,4(a2)
+ b determine_free_finalizers_after_mark
+
+finalizer_not_used_after_mark:
+ stw a2,0(a1)
+ addi a1,a2,4
+
+ lwz a2,4(a2)
+ stw a2,0(a0)
+ b determine_free_finalizers_after_mark
+
+end_finalizers_after_mark:
+ stw a2,0(a1)
+ endif
+
+ stwu o4,-4(sp)
+
+ bl .add_garbage_collect_time
+
+ lwz o4,0(sp)
+ baddi sp,4
+
+ if ADJUST_HEAP_SIZE
+ lea o0,bit_vector_size
+ lea d2,alloc_size
+ lwz d0,0(o0)
+ else
+ lea o0,heap_size_33
+ lea d2,alloc_size
+ lwz d0,0(o0)
+ slwi d0,d0,3
+ endif
+ lwz d2,0(d2)
+ slwi d4,d4,2
+ slwi d2,d2,2
+ add d2,d2,d4
+
+ if ADJUST_HEAP_SIZE
+ lea d1,heap_size_multiple
+ slwi o1,d0,2
+ lwz o2,0(d1)
+
+ mullw d1,d2,o2
+ mulhwu o2,d2,o2
+ srwi d1,d1,8
+ rlwimi d1,o2,32-8,0,7
+ srwi. o2,o2,8
+ beq+ not_largest_heap
+
+ lea d1,heap_size_33
+ lwz d1,0(d1)
+ slwi d1,d1,5
+
+not_largest_heap:
+ cmpw d1,o1
+ ble no_larger_heap
+
+ lea o1,heap_size_33
+ lwz o1,0(o1)
+ slwi o1,o1,5
+ cmpw d1,o1
+ ble not_larger_then_heap
+ mr d1,o1
+not_larger_then_heap:
+ srwi d0,d1,2
+ stw d0,0(o0)
+no_larger_heap:
+ endif
+
+ andi. r0,d0,31
+
+ srwi d5,d0,5
+
+ beq no_extra_word
+
+ rlwinm d1,d0,32-3,3,29
+ li g0,0
+ stwx g0,o4,d1
+
+no_extra_word:
+
+ lea o0,last_heap_free
+ slwi d0,d0,2
+ sub d0,d0,d4
+ stw d0,0(o0)
+
+ if COUNT_GARBAGE_COLLECTIONS
+ lea o1,n_garbage_collections
+ lwz o2,0(o1)
+ addi o2,o2,1
+ endif
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,2
+ if COUNT_GARBAGE_COLLECTIONS
+ stw o2,0(o1)
+ endif
+ beq+ _no_heap_use_message2
+
+ stwu o4,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+
+ lea o0,marked_gc_string_1
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ mr o0,d4
+ if STDERR_TO_FILE
+ bl .er_print_int
+ else
+ bl .ew_print_int
+ endif
+ lea o0,heap_use_after_gc_string_2
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ if MACOSX
+ lwz sp,0(sp)
+ lwzu o4,0(sp)
+ else
+ lwzu o4,64(sp)
+ endif
+ baddi sp,4
+
+_no_heap_use_message2:
+ if FINALIZERS
+ bl call_finalizers
+ lea o4,heap_vector
+ lwz o4,0(o4)
+ endif
+ lea d2,alloc_size
+
+ mtctr d5
+
+ lwz d2,0(d2)
+ mr a0,o4
+
+ lea o0,free_after_mark
+ li g0,0
+ stw g0,0(o0)
+
+_scan_bits:
+ lwz o0,0(a0)
+ baddi a0,4
+ cmpwi o0,0
+ beq _zero_bits
+ stw g0,-4(a0)
+ bdnz _scan_bits
+
+ b _end_scan
+
+_zero_bits:
+ mr a1,a0
+ bdnz _skip_zero_bits_lp+4
+ b _end_bits
+
+_skip_zero_bits_lp:
+ bne _end_zero_bits
+ lwz d1,0(a0)
+ baddi a0,4
+ tst d1
+ bdnz _skip_zero_bits_lp
+
+ beq _end_bits
+ stw g0,-4(a0)
+ sub d1,a0,a1
+ b _end_bits2
+
+_end_zero_bits:
+ lea o0,free_after_mark
+
+ sub d1,a0,a1
+ slwi d1,d1,3
+
+ cmplw 0,d1,d2
+
+ lwz o1,0(o0)
+ stw g0,-4(a0)
+
+ add o1,o1,d1
+ stw o1,0(o0)
+ blt _scan_bits
+
+_found_free_memory:
+ mfctr d0
+ lea o0,bit_counter
+ lea o1,bit_vector_p
+ stw d0,0(o0)
+ stw a0,0(o1)
+
+ sub d7,d1,d2
+
+ subi d0,a1,4
+ sub d0,d0,o4
+ slwi d0,d0,5
+ add a6,d0,d6
+
+ slwi d1,d1,2
+ lea o0,heap_end_after_gc
+ add d0,a6,d1
+ stw d0,0(o0)
+
+ lwz d0,0(sp)
+ lwz d1,4(sp)
+ lwz d2,8(sp)
+ lwz d3,12(sp)
+ lwz d4,16(sp)
+ lwz d5,20(sp)
+ lwz d6,24(sp)
+
+ lwz r0,28(sp)
+ mtlr r0
+
+ subi a6,a6,4
+ baddi sp,32
+ blr
+
+_end_bits:
+ sub d1,a0,a1
+ baddi d1,4
+_end_bits2:
+ lea o0,free_after_mark
+
+ slwi d1,d1,3
+
+ lwz o1,0(o0)
+ cmplw 0,d1,d2
+
+ add o1,o1,d1
+ stw o1,0(o0)
+ bge _found_free_memory
+
+_end_scan:
+ lea o0,bit_counter
+ mfctr d0
+ stw d0,0(o0)
+ b compact_gc
+
+
+ csect .mark_gc
+ export _mark_stack_nodes
+
+; a0,a1,a2,a3,a4
+; d0,d1,d2,d3,d4,d5,d6,d7
+; o0,o1,o2,o3,o4,o5
+; g0,g1,g2
+
+; g3 = 0x80000000
+
+; o3 = bit mask
+; o4 = heap_vector
+; o5 = next_caf
+
+; d3,d5 = used during pointer reversal
+; d4 = n_marked_words
+; d6 = heap_p3
+; d7 = 32*heap_size_33
+
+; a2 = pointer to next node on stack
+; a3 = end_stack
+; a4 = end_vector
+
+; a5 = not used, __cycle__in__spine
+; a6 = not used, hp
+
+_mark_stack_nodes:
+ cmpw a4,a2
+ beqlr
+
+_mark_stack_nodes_:
+ lwz a0,0(a2)
+ addi a2,a2,4
+
+ sub d1,a0,d6
+ if SHARE_CHAR_INT
+ cmplw d1,d7
+ bge- _mark_stack_nodes
+ endif
+
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ bne- _mark_stack_nodes
+
+ if MARK_USING_REVERSAL
+ addi o0,a2,-4
+ stwu o0,-4(sp)
+ li d3,0
+ li d5,1
+ b __mark__node
+
+_mark_next_node:
+ b _mark_stack_nodes
+
+ else
+ li g0,0
+ stwu g0,-4(sp)
+
+ b _mark_arguments
+
+_mark_hnf_2:
+ cmplwi 0,o3,4
+ bor o1,o3
+ stwx o1,o4,o0
+ bge+ fits_in_word_6
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_6:
+ baddi d4,3
+
+_mark_record_2_c:
+ lwz o0,4-NODE_POINTER_OFFSET(a0)
+ cmplw 0,sp,a3
+
+ stwu o0,-4(sp)
+ blt __mark_using_reversal
+
+_mark_node2:
+ lwz a0,0-NODE_POINTER_OFFSET(a0)
+
+_mark_node:
+ sub d1,a0,d6
+ if SHARE_CHAR_INT
+ cmplw d1,d7
+ bge _mark_next_node
+ endif
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ bne _mark_next_node
+
+_mark_arguments:
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+
+ srw o3,g3,d1
+
+ andi. r0,d0,2
+ lha d2,-2(d0)
+ beq _mark_lazy_node
+
+_no_mark_lazy_node:
+ tst d2
+ beq _mark_hnf_0
+
+ cmplwi 0,d2,256
+ baddi a0,4
+ bge _mark_record
+
+ subic. d2,d2,2
+ beq _mark_hnf_2
+ blt _mark_hnf_1
+
+_mark_hnf_3:
+ cmplwi 0,o3,4
+
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ bor o1,o3
+ stwx o1,o4,o0
+
+ bge+ fits_in_word_1
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_1:
+ sub d0,a1,d6
+
+ rlwinm o0,d0,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d0,d0,32-2,27,31
+ srw o3,g3,d0
+
+ and. r0,o1,o3
+ baddi d4,3
+ bne _shared_argument_part
+
+ if 0
+ srwi o2,a0,6
+ srwi g1,a1,6
+ cmpw g1,o2
+ lea o2,page_hit_counters
+ beq same_cache_line_1
+ baddi o2,4
+same_cache_line_1:
+ lwz g1,0(o2)
+ baddi g1,1
+ stw g1,0(o2)
+ endif
+
+_no_shared_argument_part:
+ slwi o2,d2,2
+ add a1,a1,o2
+
+ addi d2,d2,1
+
+ add o2,d0,d2
+ cmplwi 0,o2,32
+
+ add d4,d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble+ fits_in_word_2
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_2:
+ if NODE_POINTER_OFFSET
+ lwzu o0,0-NODE_POINTER_OFFSET(a1)
+ else
+ lwz o0,0-NODE_POINTER_OFFSET(a1)
+ endif
+ subi d2,d2,2
+ stwu o0,-4(sp)
+
+_push_hnf_args:
+ cmplw 6,sp,a3
+
+_push_hnf_args_lp:
+ lwzu o0,-4(a1)
+ subic. d2,d2,1
+ stwu o0,-4(sp)
+ bge _push_hnf_args_lp
+
+ bge 6,_mark_node2
+
+ b __mark_using_reversal
+
+_mark_hnf_1:
+ cmplwi 0,o3,2
+ bor o1,o3
+ stwx o1,o4,o0
+ bge+ fits_in_word_4
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_4:
+ baddi d4,2
+
+_shared_argument_part:
+ lwz a0,0-NODE_POINTER_OFFSET(a0)
+ b _mark_node
+
+_mark_lazy_node_1:
+ cmplwi 6,o3,4
+
+ bor o1,o3
+ baddi a0,4
+ stwx o1,o4,o0
+
+ bge+ 6,fits_in_word_3
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_3:
+; tst d2
+ baddi d4,3
+ beq _mark_node2
+
+_mark_selector_node_1:
+ baddicc d2,2
+ lwz a1,0-NODE_POINTER_OFFSET(a0)
+ beq _mark_indirection_node
+
+ sub d1,a1,d6
+
+ baddicc d2,1
+
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+
+ ble _mark_record_selector_node_1
+
+ rlwnm. r0,o1,d1,0,0
+ bne _mark_node3
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq _mark_node3
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,2
+ ble _small_tuple_or_record
+
+_large_tuple_or_record:
+ lwz d1,8(a1)
+
+ sub d1,d1,d6
+ rlwinm o0,d1,32-5,5,29
+ lwzx g1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,g1,d1,0,0
+ bne _mark_node3
+
+_small_tuple_or_record:
+ if LINUX
+ lwz g1,-8(d0)
+ else
+ lha g1,-6(d0)
+ endif
+ subi d2,a0,4
+ if LINUX
+ else
+ lwzx g1,rtoc,g1
+ endif
+ mr a0,a1
+ lwz g1,4(g1)
+
+ mtctr g1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ if REMOVE_INDIRECTION_LISTS
+ addi g2,d2,4
+ b __mark_node
+ else
+ b _mark_node
+ endif
+
+_mark_record_selector_node_1:
+ beq _mark_strict_record_selector_node_1
+
+ rlwnm. r0,o1,d1,0,0
+ bne _mark_node3
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq _mark_node3
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,258
+ ble _small_tuple_or_record
+ b _large_tuple_or_record
+
+_mark_strict_record_selector_node_1:
+ rlwnm. r0,o1,d1,0,0
+ bne _mark_node3
+
+_no_mark_strict_record_selector_node_1:
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq _mark_node3
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,258
+ ble _select_from_small_record
+
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+
+ sub d1,d1,d6
+ rlwinm o0,d1,32-5,5,29
+ lwzx g1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,g1,d1,0,0
+ bne _mark_node3
+
+_select_from_small_record:
+ if LINUX
+ lwz g1,-8(d0)
+ else
+ lha g1,-6(d0)
+ endif
+ subi a0,a0,4
+ if LINUX
+ else
+ lwzx g1,rtoc,g1
+ endif
+ lwz g1,4(g1)
+
+ mtctr g1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ b _mark_next_node
+
+_mark_indirection_node:
+
+
+ if REMOVE_INDIRECTION_LISTS
+ mr g2,a0
+__mark_indirection_node:
+ mr a0,a1
+__mark_node:
+ sub d1,a0,d6
+ if SHARE_CHAR_INT
+ cmplw d1,d7
+ bge- __mark_next_node
+ endif
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ beq __mark_arguments
+
+__mark_next_node:
+
+ lwz g1,0-NODE_POINTER_OFFSET(g2)
+ cmpw g1,a0
+ beq __end_indirection_list1
+__update_indirection_list1:
+ stw a0,0-NODE_POINTER_OFFSET(g2)
+ addi g2,g1,4
+ lwz g1,4-NODE_POINTER_OFFSET(g1)
+ cmplw g1,a0
+ bne __update_indirection_list1
+__end_indirection_list1:
+
+ b _mark_next_node
+
+__mark_arguments:
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+
+ srw o3,g3,d1
+
+ andi. r0,d0,2
+ lha d2,-2(d0)
+ beq __mark_lazy_node
+
+ lwz g1,0-NODE_POINTER_OFFSET(g2)
+ cmpw g1,a0
+ beq __end_indirection_list2
+__update_indirection_list2:
+ stw a0,0-NODE_POINTER_OFFSET(g2)
+ addi g2,g1,4
+ lwz g1,4-NODE_POINTER_OFFSET(g1)
+ cmplw g1,a0
+ bne __update_indirection_list2
+__end_indirection_list2:
+
+ b _no_mark_lazy_node
+
+__mark_lazy_node:
+ tst d2
+ blt __mark_lazy_node_lt0
+
+ lwz g1,0-NODE_POINTER_OFFSET(g2)
+ cmpw g1,a0
+ beq __end_indirection_list3
+__update_indirection_list3:
+ stw a0,0-NODE_POINTER_OFFSET(g2)
+ addi g2,g1,4
+ lwz g1,4(g1)
+ cmplw g1,a0
+ bne __update_indirection_list3
+__end_indirection_list3:
+
+ b _mark_lazy_node
+
+__mark_lazy_node_lt0:
+ baddicc d2,2
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ beq __mark_indirection_node
+
+ sub d1,a1,d6
+
+ baddicc d2,1
+
+ rlwinm g0,d1,32-5,5,29
+ lwzx g1,o4,g0
+ rlwinm d1,d1,32-2,27,31
+
+ ble __mark_record_selector_node_1
+
+ rlwnm. r0,g1,d1,0,0
+ bne __mark_node3
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq __mark_node3
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,2
+ ble __small_tuple_or_record
+
+__large_tuple_or_record:
+ lwz d1,8-NODE_POINTER_OFFSET(a1)
+
+ sub d1,d1,d6
+ rlwinm g0,d1,32-5,5,29
+ lwzx g1,o4,g0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,g1,d1,0,0
+ bne __mark_node3
+
+__small_tuple_or_record:
+ if LINUX
+ lwz g1,-8(d0)
+ else
+ lha g1,-6(d0)
+ endif
+ mr d2,a0
+ if LINUX
+ else
+ lwzx g1,rtoc,g1
+ endif
+ mr a0,a1
+ lwz g1,4(g1)
+
+ mtctr g1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ b __mark_node
+
+__mark_record_selector_node_1:
+ beq __mark_strict_record_selector_node_1
+
+ rlwnm. r0,g1,d1,0,0
+ bne __mark_node3
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq __mark_node3
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,258
+ ble __small_tuple_or_record
+ b __large_tuple_or_record
+
+__mark_node3:
+ cmplwi 6,o3,4
+
+ bor o1,o3
+ stwx o1,o4,o0
+
+ bge+ 6,_fits_in_word_3
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+_fits_in_word_3:
+ baddi d4,3
+
+ lwz g1,0-NODE_POINTER_OFFSET(g2)
+ cmpw g1,a0
+ beq __end_indirection_list4
+__update_indirection_list4:
+ stw a0,0-NODE_POINTER_OFFSET(g2)
+ addi g2,g1,4
+ lwz g1,4-NODE_POINTER_OFFSET(g1)
+ cmplw g1,a0
+ bne __update_indirection_list4
+__end_indirection_list4:
+
+ mr a0,a1
+ b _mark_node
+
+__mark_strict_record_selector_node_1:
+ rlwnm. r0,g1,d1,0,0
+ bne __mark_node3
+
+ cmplwi 6,o3,4
+
+ bor o1,o3
+ stwx o1,o4,o0
+
+ bge+ 6,_fits_in_word_3_
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+_fits_in_word_3_:
+ baddi d4,3
+
+ lwz g1,0-NODE_POINTER_OFFSET(g2)
+ cmpw g1,a0
+ beq __end_indirection_list5
+__update_indirection_list5:
+ stw a0,0-NODE_POINTER_OFFSET(g2)
+ addi g2,g1,4
+ lwz g1,4-NODE_POINTER_OFFSET(g1)
+ cmplw g1,a0
+ bne __update_indirection_list5
+__end_indirection_list5:
+
+ baddi a0,4
+ b _no_mark_strict_record_selector_node_1
+ endif
+
+_mark_node3:
+ mr a0,a1
+ b _mark_node
+
+_mark_next_node:
+ lwz a0,0(sp)
+ baddi sp,4
+ tst a0
+ bne _mark_node
+
+ cmpw a4,a2
+ bne _mark_stack_nodes_
+
+_end_mark_nodes:
+ blr
+
+_mark_lazy_node:
+ tst d2
+ beq _mark_real_or_file
+
+ cmpwi 0,d2,1
+ ble _mark_lazy_node_1
+
+ cmplwi 0,d2,256
+ bge _mark_closure_with_unboxed_arguments
+ baddi d2,1
+
+ add o2,d1,d2
+ cmpwi 0,o2,32
+
+ add d4,d4,d2
+ bor o1,o3
+ stwx o1,o4,o0
+
+ ble+ fits_in_word_7
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_7:
+ slwi g2,d2,2
+ add a0,a0,g2
+
+ cmplw 6,sp,a3
+
+ subi d2,d2,3
+_push_lazy_args:
+ lwzu o0,-4(a0)
+ subic. d2,d2,1
+ stwu o0,-4(sp)
+ bge _push_lazy_args
+
+ bsubi a0,4
+
+ bge 6,_mark_node2
+
+ b __mark_using_reversal
+
+_mark_closure_with_unboxed_arguments:
+ srwi g2,d2,8
+ bandic d2,255
+
+ bsubicc d2,1
+ beq _mark_real_or_file
+
+ baddi d2,2
+
+ add o2,d1,d2
+ cmpwi 0,o2,32
+
+ badd d4,d2
+ bor o1,o3
+ stwx o1,o4,o0
+
+ ble+ fits_in_word_7_
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_7_:
+ bsub d2,g2
+ slwi g2,d2,2
+
+ bsubicc d2,2
+ blt- _mark_next_node
+
+ badd a0,g2
+
+ cmplw 6,sp,a3
+ bne _push_lazy_args
+
+_mark_closure_with_one_boxed_argument:
+ lwz a0,-4(a0)
+ b _mark_node
+
+_mark_hnf_0:
+ cmplw 0,d0,int_reg
+ blt _mark_real_file_or_string
+
+ cmplw d0,char_reg
+ bgt _mark_normal_hnf_0
+
+_mark_bool_or_small_string:
+ cmplwi 0,o3,2
+ bor o1,o3
+
+ stwx o1,o4,o0
+ baddi d4,2
+
+ bge+ _mark_next_node
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b _mark_next_node
+
+_mark_normal_hnf_0:
+ bor o1,o3
+ baddi d4,1
+ stwx o1,o4,o0
+ b _mark_next_node
+
+_mark_real_file_or_string:
+ lea g1,__STRING__2
+ cmplw 0,d0,g1
+ ble _mark_string_or_array
+
+_mark_real_or_file:
+ cmplwi 0,o3,4
+ bor o1,o3
+
+ stwx o1,o4,o0
+ baddi d4,3
+
+ bge+ _mark_next_node
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b _mark_next_node
+
+_mark_record:
+ subic. d2,d2,258
+ beq _mark_record_2
+ blt _mark_record_1
+
+_mark_record_3:
+ cmplwi 0,o3,4
+
+ lhz d1,-2+2(d0)
+
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,3
+
+ bge+ fits_in_word_13
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+fits_in_word_13:
+
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+
+ subic. d1,d1,1
+
+ sub d0,a1,d6
+ rlwinm o0,d0,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d0,d0,32-2,27,31
+ srw o3,g3,d0
+
+ blt _mark_record_3_bb
+
+ and. r0,o3,o1
+ bne _mark_node2
+
+ addi d2,d2,1
+
+ add o2,d0,d2
+ cmplwi 0,o2,32
+
+ add d4,d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble+ _push_record_arguments
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+_push_record_arguments:
+ subic. d2,d1,1
+
+ slwi d1,d1,2
+ add a1,a1,d1
+ if NODE_POINTER_OFFSET
+ bsubi a1,NODE_POINTER_OFFSET
+ endif
+ bge _push_hnf_args
+
+ b _mark_node2
+
+_mark_record_3_bb:
+ and. r0,o3,o1
+ bne _mark_next_node
+
+ addi d2,d2,1
+
+ add o2,d0,d2
+ cmplwi 0,o2,32
+
+ add d4,d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble _mark_next_node
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b _mark_next_node
+
+_mark_record_2:
+ cmplwi 0,o3,4
+
+ lhz g1,-2+2(d0)
+ bor o1,o3
+
+ cmplwi 6,g1,1
+
+ stwx o1,o4,o0
+ bge+ fits_in_word_12
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits_in_word_12:
+ baddi d4,3
+
+ bgt 6,_mark_record_2_c
+ beq 6,_mark_node2
+ b _mark_next_node
+
+_mark_record_1:
+ lhz g1,-2+2(d0)
+ tst g1
+ bne _mark_hnf_1
+
+ b _mark_bool_or_small_string
+
+_mark_string_or_array:
+ beq _mark_string_
+
+_mark_array:
+ lwz d1,8-NODE_POINTER_OFFSET(a0)
+ tst d1
+ beq _mark_lazy_array
+
+ lhz d0,-2(d1)
+ tst d0
+ beq _mark_strict_basic_array
+
+ lhz d1,-2+2(d1)
+ tst d1
+ beq _mark_b_record_array
+
+ cmplw 0,sp,a3
+ blt __mark_array_using_reversal
+
+ subi d3,d0,256
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+
+ cmplw 0,d1,d3
+ bor o1,o3
+
+ stwx o1,o4,o0
+ baddi d4,1
+
+ mullw d0,d2,d3
+
+ beq _mark_lazy_or_a_record_array
+
+_mark_ab_record_array:
+ baddi d0,3-1
+
+ badd d4,d0
+ slwi d0,d0,2
+
+ badd d0,a0
+
+ sub d0,d0,d6
+ rlwinm d0,d0,32-5,5,29
+
+ cmplw 0,o0,d0
+ bge _end_set_ab_array_bits
+
+ baddi o0,4
+ cmplw 0,o0,d0
+ bge _last_ab_array_bits
+
+_mark_ab_array_lp:
+ stwx g3,o4,o0
+ baddi o0,4
+ cmplw 0,o0,d0
+ blt _mark_ab_array_lp
+
+_last_ab_array_bits:
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+_end_set_ab_array_bits:
+ mflr o1
+ stw a2,-8(sp)
+
+ stw a4,-4(sp)
+ slwi d3,d3,2
+
+ addi a2,a0,12-NODE_POINTER_OFFSET
+ stw d3,-20(sp)
+
+ slwi d1,d1,2
+ stw d1,-16(sp)
+
+ cmplwi 0,d2,0
+
+ stw o1,-12(sp)
+ subi sp,sp,28
+
+ beq _mark_ab_array_0
+
+_mark_ab_array:
+ lwz d1,12(sp)
+ stw d2,4(sp)
+ stw a2,0(sp)
+
+ add a4,a2,d1
+ bl _mark_stack_nodes
+
+ lwz d2,4(sp)
+ lwz a2,0(sp)
+ subic. d2,d2,1
+ lwz d3,8(sp)
+ add a2,a2,d3
+ bne _mark_ab_array
+
+_mark_ab_array_0:
+ lwz o1,16(sp)
+ baddi sp,28
+
+ lwz a2,-8(sp)
+ mtlr o1
+ lwz a4,-4(sp)
+ b _mark_next_node
+
+_mark_lazy_array:
+ cmplw 0,sp,a3
+ blt __mark_array_using_reversal
+
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ bor o1,o3
+
+ stwx o1,o4,o0
+ baddi d4,1
+
+_mark_lazy_or_a_record_array:
+ mr d2,d0
+ baddi d0,3-1
+
+ badd d4,d0
+ slwi d0,d0,2
+
+ badd d0,a0
+
+ sub d0,d0,d6
+ rlwinm d0,d0,32-5,5,29
+
+ cmplw 0,o0,d0
+ bge _end_set_lazy_array_bits
+
+ baddi o0,4
+ cmplw 0,o0,d0
+ bge _last_lazy_array_bits
+
+_mark_lazy_array_lp:
+ stwx g3,o4,o0
+ baddi o0,4
+ cmplw 0,o0,d0
+ blt _mark_lazy_array_lp
+
+_last_lazy_array_bits:
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+_end_set_lazy_array_bits:
+ mflr d1
+ stw a2,-8(sp)
+
+ addi a2,a0,12--NODE_POINTER_OFFSET
+ stw a4,-4(sp)
+
+ slwi d2,d2,2
+ stwu d1,-12(sp)
+
+ add a4,a2,d2
+ bl _mark_stack_nodes
+
+ lwz d1,0(sp)
+ baddi sp,12
+
+ lwz a2,-8(sp)
+ mtlr d1
+
+ lwz a4,-4(sp)
+ b _mark_next_node
+
+__mark_array_using_reversal:
+ li d3,0
+ stwu d3,-4(sp)
+ li d5,1
+ b __mark__node
+
+_mark_strict_basic_array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ cmplw 0,d1,int_reg
+ beq _mark_strict_int_array
+ cmplw 0,d1,bool_reg
+ beq _mark_strict_bool_array
+_mark_strict_real_array:
+ badd d0,d0
+_mark_strict_int_array:
+ addi d0,d0,3
+ b _mark_basic_array_
+_mark_strict_bool_array:
+ addi d0,d0,12+3
+ srwi d0,d0,2
+ b _mark_basic_array_
+
+_mark_b_record_array:
+ lwz d1,4-NODE_POINTER_OFFSET(a0)
+ subi d0,d0,256
+ mullw d0,d0,d1
+ addi d0,d0,3
+ b _mark_basic_array_
+
+_mark_string_:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi d0,d0,8+3
+ srwi d0,d0,2
+
+_mark_basic_array_:
+ bor o1,o3
+ stwx o1,o4,o0
+
+ add d4,d4,d0
+
+ slwi d0,d0,2
+ badd d0,a0
+ subi d0,d0,4
+
+ sub d0,d0,d6
+ rlwinm d0,d0,32-5,5,29
+
+ cmplw 0,o0,d0
+ bge _mark_next_node
+
+ baddi o0,4
+ cmplw 0,o0,d0
+ bge _last_string_bits
+
+_mark_string_lp:
+ stwx g3,o4,o0
+ baddi o0,4
+ cmplw 0,o0,d0
+ blt _mark_string_lp
+
+_last_string_bits:
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b _mark_next_node
+ endif
+
+
+
+__end__mark__using__reversal:
+ lwz a1,0(sp)
+ baddi sp,4
+ tst a1
+ beq _mark_next_node
+ stw a0,0(a1)
+ b _mark_next_node
+
+__end__mark__using__reversal__after__static:
+ lwz a1,0(sp)
+ baddi sp,4
+ stw a0,0(a1)
+ b _mark_next_node
+
+__mark_using_reversal:
+ stwu a0,-4(sp)
+ li d3,0
+ lwz a0,0(a0)
+ li d5,1
+ b __mark__node
+
+__mark__arguments:
+ lwz d0,0-NODE_POINTER_OFFSET(a0)
+ srw o3,g3,d1
+
+ andi. r0,d0,2
+ lha d2,-2(d0)
+
+ beq __mark__lazy__node
+
+ tst d2
+ beq __mark__hnf__0
+
+ cmplwi 0,d2,256
+ baddi a0,4
+ bge __mark__record
+
+ subic. d2,d2,2
+ beq __mark__hnf__2
+ blt __mark__hnf__1
+
+__mark__hnf__3:
+ cmplwi 0,o3,4
+
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+ bor o1,o3
+ stwx o1,o4,o0
+
+ bge+ fits__in__word__1
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word__1:
+ sub d0,a1,d6
+
+ rlwinm o0,d0,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d0,d0,32-2,27,31
+ srw o3,g3,d0
+
+ and. r0,o1,o3
+ baddi d4,3
+ bne __shared__argument__part
+
+__no__shared__argument__part:
+ or d3,d3,d5
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ lwz g1,0-NODE_POINTER_OFFSET(a1)
+ slwi d1,d2,2
+
+ addi d2,d2,1
+ add o2,d0,d2
+ cmplwi o2,32
+
+ ori g1,g1,1
+ stw g1,0(a1)
+
+ add d4,d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+
+ ble+ fits__in__word__2
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word__2:
+ lwzux d2,a1,d1
+ li d5,0
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b __mark__node
+
+__mark__lazy__node__1:
+ bne __mark__selector__node__1
+
+__mark__selector__1:
+ cmplwi 0,o3,4
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,3
+ bge+ __shared__argument__part
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b __shared__argument__part
+
+__mark__hnf__1:
+ cmplwi 0,o3,2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,2
+
+ bge+ __shared__argument__part
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+__shared__argument__part:
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ bor d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,2
+ mr a0,d2
+ b __mark__node
+
+__mark__selector__node__1:
+ baddicc d2,2
+ lwz a1,0-NODE_POINTER_OFFSET(a0)
+ beq __mark__indirection__node
+
+ sub o2,a1,d6
+
+ addic. d2,d2,1
+
+ rlwinm d2,o2,32-5,5,29
+ lwzx g1,o4,d2
+ rlwinm o2,o2,32-2,27,31
+
+ ble __mark__record__selector__node__1
+
+ rlwnm. r0,g1,o2,0,0
+ bne- __mark__selector__1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq- __mark__selector__1
+
+ lha g1,-2(d2)
+ cmplwi 0,g1,2
+ ble __small__tuple__or__record
+
+__large__tuple__or__record:
+ lwz o2,8-NODE_POINTER_OFFSET(a1)
+ sub o2,o2,d6
+
+ rlwinm d2,o2,32-5,5,29
+ lwzx g1,o4,d2
+ rlwinm o2,o2,32-2,27,31
+ srw g2,g3,o2
+
+ and. r0,g2,g1
+ bne- __mark__selector__1
+
+__small__tuple__or__record:
+ if LINUX
+ lwz g1,-8(d0)
+ else
+ lha g1,-6(d0)
+ endif
+ subi d2,a0,4
+ if LINUX
+ else
+ lwzx g1,rtoc,g1
+ endif
+ mr a0,a1
+ lwz g1,4(g1)
+
+ mtctr g1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lea g1,__indirection
+ stw a0,4-NODE_POINTER_OFFSET(d2)
+ stw g1,0-NODE_POINTER_OFFSET(d2)
+ b __mark__node
+
+__mark__record__selector__node__1:
+ beq __mark__strict__record__selector__node__1
+
+ rlwnm. r0,g1,o2,0,0
+ bne- __mark__selector__1
+
+ lwz d2,0(a1)
+ andi. r0,d2,2
+ beq- __mark__selector__1
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,258
+ ble __small__tuple__or__record
+ b __large__tuple__or__record
+
+__mark__strict__record__selector__node__1:
+ rlwnm. r0,g1,o2,0,0
+ bne- __mark__selector__1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ andi. r0,d2,2
+ beq- __mark__selector__1
+
+ lhz g1,-2(d2)
+ cmplwi 0,g1,258
+ ble __select__from__small__record
+
+ lwz o2,8-NODE_POINTER_OFFSET(a1)
+ sub o2,o2,d6
+
+ rlwinm d2,o2,32-5,5,29
+ lwzx g1,o4,d2
+ rlwinm o2,o2,32-2,27,31
+ rlwnm. r0,g1,o2,0,0
+ bne- __mark__selector__1
+
+__select__from__small__record:
+ if LINUX
+ lwz g1,-8(d0)
+ else
+ lha g1,-6(d0)
+ endif
+ subi a0,a0,4
+ if LINUX
+ else
+ lwzx g1,rtoc,g1
+ endif
+ lwz g1,4(g1)
+
+ mtctr g1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ b __mark__node
+
+__mark__indirection__node:
+ mr a0,a1
+ b __mark__node
+
+__mark__hnf__2:
+ cmplwi 0,o3,4
+
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,3
+
+ bge+ fits__in__word__6
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+fits__in__word__6:
+
+__mark__record__2__c:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+ lwzu d2,4-NODE_POINTER_OFFSET(a0)
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+
+__mark__node:
+ sub d1,a0,d6
+ if SHARE_CHAR_INT
+ cmplw d1,d7
+ bge- __mark__next__node__after__static
+ endif
+
+ rlwinm o0,d1,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d1,d1,32-2,27,31
+ rlwnm. r0,o1,d1,0,0
+ beq __mark__arguments
+
+__mark__next__node:
+ tst d5
+ bne __mark__parent
+
+__mark__next__node2:
+ lwzu d2,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ andi. d5,d2,3
+
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+
+ stw a0,4-NODE_POINTER_OFFSET(d3)
+ clrrwi a0,d2,2
+ b __mark__node
+
+__mark__lazy__node:
+ tst d2
+ beq __mark__real__or__file
+
+ cmpwi 0,d2,1
+ baddi a0,4
+ ble __mark__lazy__node__1
+
+ cmplwi 0,d2,256
+ bge __mark_closure_with_unboxed_arguments
+ baddi d2,1
+
+ add o2,d1,d2
+ cmplwi 0,o2,32
+
+ add d4,d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble+ fits__in__word__7
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word__7:
+ subi d2,d2,2
+
+__mark_closure_with_unboxed_arguments__2:
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ slwi d2,d2,2
+ ori o0,o0,2
+ stw o0,0-NODE_POINTER_OFFSET(a0)
+
+ lwzux d2,a0,d2
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,0
+ mr a0,d2
+ b __mark__node
+
+__mark_closure_with_unboxed_arguments:
+ srwi d0,d2,8
+ bandic d2,255
+
+ bsubicc d2,1
+ beq __mark_closure_1_with_unboxed_argument
+
+ baddi d2,2
+ add o2,d1,d2
+ cmplwi 0,o2,32
+
+ badd d4,d2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble+ fits__in__word__7_
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word__7_:
+ bsub d2,d0
+ bsubicc d2,2
+ bgt __mark_closure_with_unboxed_arguments__2
+ beq __shared__argument__part
+ bsubi a0,4
+ b __mark__next__node
+
+__mark_closure_1_with_unboxed_argument:
+ bsubi a0,4
+ b __mark__real__or__file
+
+__mark__hnf__0:
+ cmplw d0,int_reg
+ bne __no__int__3
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ cmplwi 0,d2,33
+ slwi d2,d2,3
+ blt ____small____int
+
+__mark__bool__or__small__string:
+ cmplwi 0,o3,2
+
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,2
+
+ bge+ __mark__next__node
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b __mark__next__node
+
+____small____int:
+ lea a0,small_integers
+ add a0,a0,d2
+ b __mark__next__node__after__static
+
+__no__int__3:
+ blt __mark__real__file__or__string
+
+ cmplw 0,d0,char_reg
+ bne __no__char__3
+
+ lbz d2,7-NODE_POINTER_OFFSET(a0)
+ lea a0,static_characters
+ slwi d2,d2,3
+ add a0,a0,d2
+ b __mark__next__node__after__static
+
+__no__char__3:
+ blt __mark__bool__or__small__string
+
+ subi a0,d0,2-ZERO_ARITY_DESCRIPTOR_OFFSET
+ b __mark__next__node__after__static
+
+__mark__real__file__or__string:
+ lea g1,__STRING__2
+ cmplw 0,d0,g1
+ ble __mark__string__or__array
+
+__mark__real__or__file:
+ cmplwi 0,o3,4
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,3
+ bge+ __mark__next__node
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b __mark__next__node
+
+__mark__record:
+ subic. d2,d2,258
+ beq __mark__record__2
+ blt __mark__record__1
+
+__mark__record__3:
+ cmplwi 0,o3,4
+
+ bor o1,o3
+ stwx o1,o4,o0
+ baddi d4,3
+
+ lwz a1,4-NODE_POINTER_OFFSET(a0)
+
+ bge+ fits__in__word__13
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+fits__in__word__13:
+
+ lhz d1,-2+2(d0)
+
+ sub d0,a1,d6
+ rlwinm o0,d0,32-5,5,29
+ lwzx o1,o4,o0
+ rlwinm d0,d0,32-2,27,31
+ srw o3,g3,d0
+
+ and. r0,o3,o1
+ bne __shared__record__argument__part
+
+ addi d2,d2,1
+
+ add o2,d0,d2
+ cmplwi 6,o2,32
+
+ add d4,d4,d2
+
+ subic. d1,d1,1
+
+ bor o1,o3
+ stwx o1,o4,o0
+ ble+ 6,fits__in__word__14
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word__14:
+ blt __mark__record__3__bb
+ beq __shared__argument__part
+
+ subic. d1,d1,1
+ or d3,d3,d5
+ stwu d3,4-NODE_POINTER_OFFSET(a0)
+
+ beq __mark__record__3__aab
+
+ lwz g1,0-NODE_POINTER_OFFSET(a1)
+ slwi d1,d1,2
+ ori g1,g1,1
+ stw g1,0-NODE_POINTER_OFFSET(a1)
+
+ lwzux d2,a1,d1
+ li d5,0
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ mr a0,d2
+ b __mark__node
+
+__mark__record__3__bb:
+ subi a0,a0,4
+ b __mark__next__node
+
+__mark__record__3__aab:
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ stw a0,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ li d5,1
+ mr a0,d2
+ b __mark__node
+
+__shared__record__argument__part:
+ tst d1
+ bne __shared__argument__part
+ subi a0,a0,4
+ b __mark__next__node
+
+__mark__record__2:
+ cmplwi 0,o3,4
+
+ lhz g1,-2+2(d0)
+ bor o1,o3
+
+ cmplwi 6,g1,1
+ baddi d4,3
+
+ stwx o1,o4,o0
+ bge+ fits__in__word_12
+
+ baddi o0,4
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+
+fits__in__word_12:
+ bgt 6,__mark__record__2__c
+ beq 6,__shared__argument__part
+ subi a0,a0,4
+ b __mark__next__node
+
+__mark__record__1:
+ lhz g1,-2+2(d0)
+ tst g1
+ bne __mark__hnf__1
+ subi a0,a0,4
+ b __mark__bool__or__small__string
+
+__mark__string__or__array:
+ beq __mark__string__
+
+__mark__array:
+ lwz d1,8-NODE_POINTER_OFFSET(a0)
+ tst d1
+ beq __mark__lazy__array
+
+ lhz d0,-2(d1)
+ tst d0
+ beq __mark__strict__basic__array
+
+ lhz d1,-2+2(d1)
+ tst d1
+ beq __mark__b__record__array
+
+ subi d0,d0,256
+ cmpw 0,d0,d1
+ beq __mark__a__record__array
+
+__mark__ab__record__array:
+ mr o2,d2
+ mr g0,d3
+ mr g1,d4
+ mr g2,d5
+
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,8
+ stw a0,-4(sp)
+
+ slwi d2,d2,2
+ mullw a1,d2,d0
+
+ sub d0,d0,d1
+ baddi a0,4
+ add a1,a0,a1
+
+ mflr r0
+ stw o0,-8(sp)
+ stw o1,-12(sp)
+ stw r0,-16(sp)
+
+ bl reorder
+
+ lwz o0,-8(sp)
+ lwz o1,-12(sp)
+ lwz r0,-16(sp)
+
+ lwz a0,-4(sp)
+ mtlr r0
+
+ mr d5,g2
+ mr d4,g1
+ mr d3,g0
+ mr d2,o2
+
+ lwz g1,-4(a0)
+ mr a1,d0
+ mullw d0,d1,g1
+ mullw d1,a1,g1
+ badd d4,d1
+ badd d1,d0
+
+; to do add n b elements to d4
+
+ slwi d1,d1,2
+ add d1,a0,d1
+ sub d1,d1,d6
+
+ slwi a1,d0,2
+ add a1,a0,a1
+ b __mark__r__array
+
+__mark__a__record__array:
+ lwz g1,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,8
+ mullw d0,d0,g1
+ b __mark__lr__array
+
+__mark__lazy__array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,8
+
+__mark__lr__array:
+ slwi a1,d0,2
+ add a1,a0,a1
+
+ sub d1,a1,d6
+__mark__r__array:
+ rlwinm d1,d1,32-5,5,29
+
+ cmplw 0,o0,d1
+
+ bor o1,o3
+ stwx o1,o4,o0
+
+ bge __skip__mark__lazy__array__bits
+
+__mark__lazy__array__bits:
+ baddi o0,4
+ lwzx o1,o4,o0
+ cmplw 0,o0,d1
+ bor o1,g3
+ stwx o1,o4,o0
+ blt __mark__lazy__array__bits
+
+__skip__mark__lazy__array__bits:
+ cmplwi d0,1
+
+ baddi d4,3
+ add d4,d4,d0
+ lea o2,lazy_array_list
+
+ ble __mark__array__length__0__1
+
+ lwz d2,0-NODE_POINTER_OFFSET(a1)
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ stw d2,0-NODE_POINTER_OFFSET(a0)
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a1)
+ lwz o1,0(o2)
+ addi d2,d2,2
+ stw o1,0-NODE_POINTER_OFFSET(a1)
+ stw d2,-4-NODE_POINTER_OFFSET(a0)
+ stwu d0,-8-NODE_POINTER_OFFSET(a0)
+ stw a0,0(o2)
+
+ lwzu d2,-4-NODE_POINTER_OFFSET(a1)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a1)
+ mr d3,a1
+ li d5,0
+ mr a0,d2
+ b __mark__node
+
+__mark__array__length__0__1:
+ subi a0,a0,8
+ blt __mark__next__node
+
+ lwz d1,12-NODE_POINTER_OFFSET(a0) ; element
+ lwz o0,8-NODE_POINTER_OFFSET(a0) ; element descriptor
+ lwz o3,0(o2)
+ stw o0,12-NODE_POINTER_OFFSET(a0)
+ stw o3,8-NODE_POINTER_OFFSET(a0)
+ stw d0,0-NODE_POINTER_OFFSET(a0)
+
+ stw a0,0(o2)
+ stwu d1,4-NODE_POINTER_OFFSET(a0)
+
+ lwz d2,0-NODE_POINTER_OFFSET(a0)
+ or d3,d3,d5
+ stw d3,0-NODE_POINTER_OFFSET(a0)
+ mr d3,a0
+ li d5,2
+ mr a0,d2
+ b __mark__node
+
+__mark__b__record__array:
+ lwz d1,4-NODE_POINTER_OFFSET(a0)
+ subi d0,d0,256
+ mullw d0,d0,d1
+ addi d0,d0,3
+ b __mark__basic__array
+
+__mark__strict__basic__array:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ cmplw 0,d1,int_reg
+ beq __mark__strict__int__array
+ cmplw 0,d1,bool_reg
+ beq __mark__strict__bool__array
+__mark__strict__real__array:
+ badd d0,d0
+__mark__strict__int__array:
+ addi d0,d0,3
+ b __mark__basic__array
+__mark__strict__bool__array:
+ addi d0,d0,12+3
+ srwi d0,d0,2
+ b __mark__basic__array
+
+__mark__string__:
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ addi d0,d0,8+3
+ srwi d0,d0,2
+
+__mark__basic__array:
+ bor o1,o3
+ stwx o1,o4,o0
+
+ add d4,d4,d0
+
+ slwi d0,d0,2
+ badd d0,a0
+ subi d0,d0,4
+
+ sub d0,d0,d6
+ rlwinm d0,d0,32-5,5,29
+
+ cmplw 0,o0,d0
+ bge __mark__next__node
+
+ baddi o0,4
+ cmplw 0,o0,d0
+ bge __last__string__bits
+
+__mark__string__lp:
+ stwx g3,o4,o0
+ baddi o0,4
+ cmplw 0,o0,d0
+ blt __mark__string__lp
+
+__last__string__bits:
+ lwzx o1,o4,o0
+ bor o1,g3
+ stwx o1,o4,o0
+ b __mark__next__node
+
+__mark__parent:
+ tst d3
+ beq __end__mark__using__reversal
+
+ subic. d5,d5,1
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ beq __argument__part__parent
+
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b __mark__next__node
+
+__argument__part__parent:
+ mr a1,d3
+
+ clrrwi d3,d2,2
+
+ lwzu a0,-4-NODE_POINTER_OFFSET(d3)
+ lwz o0,4-NODE_POINTER_OFFSET(d3)
+ li d5,2
+ stw o0,0-NODE_POINTER_OFFSET(d3)
+ stw a1,4-NODE_POINTER_OFFSET(d3)
+ b __mark__node
+
+__mark__next__node__after__static:
+ tst d5
+ beq __mark__next__node2
+
+ tst d3
+ beq __end__mark__using__reversal__after__static
+
+ subic. d5,d5,1
+ lwz d2,0-NODE_POINTER_OFFSET(d3)
+ stw a0,0-NODE_POINTER_OFFSET(d3)
+ beq __argument__part__parent
+
+ subi a0,d3,4
+ andi. d5,d2,3
+ clrrwi d3,d2,2
+ b __mark__next__node
+
+ csect text{PR}
diff --git a/pprofile.a b/pprofile.a
new file mode 100644
index 0000000..7adc9f2
--- /dev/null
+++ b/pprofile.a
@@ -0,0 +1,1407 @@
+
+ string asis
+
+ macro
+ lea &r,&a
+ lwz &r,&a{TC}(RTOC)
+ endm
+
+MACOSX set 1
+; POWER601 set 1
+ALLOCATION_PROFILE set 1
+USE_TEMPORARY_MEMORY set 1
+CHECK_STACK_OVERFLOWS set 0
+MODULE_NAMES set 1
+
+ if POWER601
+ macro
+ time_hi &r
+ dialect Power
+ mfrtcu &r
+ dialect PowerPC
+ endm
+
+ macro
+ time_lo &r
+ dialect Power
+ mfrtcl &r
+ dialect PowerPC
+ endm
+ else
+ macro
+ time_hi &r
+ mftbu &r
+ endm
+
+ macro
+ time_lo &r
+ mftb &r
+ endm
+ endif
+
+d0: set r24
+d1: set r25
+d2: set r26
+d3: set r27
+d4: set r28
+d5: set r29
+d6: set r30
+d7: set r31
+
+a0: set r23
+a1: set r22
+a2: set r21
+a3: set r20
+a4: set r19
+a5: set r18
+a6: set r17
+
+o0: set r3
+o1: set r4
+o2: set r5
+o3: set r6
+o4: set r7
+o5: set r8
+
+g2: set r9
+g3: set r10
+
+g0: set r11
+g1: set r12
+
+int_reg set r16
+char_reg set r15
+real_reg set r14
+bool_reg set r13
+
+ if POWER601
+lo1e9 set 1000000000 % 65536
+hi1e9 set (1000000000 / 65536)+1
+ endif
+
+ export init_profiler
+ export profile_r
+ export profile_l
+ export profile_l2
+ export profile_n
+ export profile_n2
+ export profile_s
+ export profile_s2
+ export profile_t
+ export profile_ti
+ export write_profile_information
+ export write_profile_stack
+
+ if USE_TEMPORARY_MEMORY
+ import .TempNewHandle
+ import .TempHLock
+ import .TempHUnlock
+ import .TempDisposeHandle
+ else
+ import .NewPtr
+ endif
+ import .Gestalt
+ import __STRING__
+ import openF
+ import closeF
+ import writeFC
+ import writeFI
+ import print_error
+ import new_file_creator
+ import stack_size
+ import .er_print_string
+ import .er_print_char
+ import .create_profile_file_name
+ if CHECK_STACK_OVERFLOWS
+ import .Debugger
+ endif
+
+FunctionProfile: record
+next: ds.l 1
+time_hi: ds.l 1
+time_lo: ds.l 1
+n_profiler_calls: ds.l 1
+n_strict_calls: ds.l 1
+n_lazy_calls: ds.l 1
+n_curried_calls: ds.l 1
+n_words_allocated: ds.l 1
+name: ds.l 1
+ endr
+
+ csect .profile_t
+profile_ti:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ lea r5,profile_globals
+ b profile_t_
+
+profile_t:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ mtctr r12
+ mtlr r0
+profile_t_:
+ lwz r6,Globals.stack_pointer(r5)
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ lwzu r4,-4(r6)
+ stw r6,Globals.stack_pointer(r5)
+ stw r4,Globals.last_tail_call(r5)
+
+ if POWER601
+ sub. r10,r10,r8
+ sub r9,r9,r7
+ bge+ @no_borrow
+ addis r10,r10,hi1e9
+ addi r10,r10,lo1e9
+ subi r9,r9,1
+@no_borrow:
+ else
+ subc r10,r10,r8
+ subfe r9,r7,r9
+ endif
+ lwz r8,FunctionProfile.time_lo(r4)
+ lwz r7,FunctionProfile.time_hi(r4)
+
+ if POWER601
+ add r8,r8,r10
+ add r7,r7,r9
+
+ subis r9,r8,hi1e9
+ cmpwi 0,r9,lo1e9
+
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+
+ blt+ @no_carry
+
+ subi r8,r9,lo1e9
+ addi r7,r7,1
+
+@no_carry:
+ else
+ addc r8,r8,r10
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+ adde r7,r7,r9
+ endif
+ addi r6,r6,1
+ stw r7,FunctionProfile.time_hi(r4)
+ stw r8,FunctionProfile.time_lo(r4)
+ stw r6,FunctionProfile.n_profiler_calls(r4)
+
+ if ALLOCATION_PROFILE
+ lwz r11,Globals.n_words_free(r5)
+ stw d7,Globals.n_words_free(r5)
+ lwz r12,FunctionProfile.n_words_allocated(r4)
+ sub r11,r11,d7
+ add r12,r12,r11
+ stw r12,FunctionProfile.n_words_allocated(r4)
+ endif
+
+@store_clock:
+ time_hi r9
+ stw r9,Globals.time_hi(r5)
+ time_lo r10
+ time_hi r4
+ stw r10,Globals.time_lo(r5)
+ cmpw 0,r4,r9
+ beqctr+
+
+ b @store_clock
+
+ csect .profile_r
+profile_r:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ lea r5,profile_globals
+
+ lwz r6,Globals.stack_pointer(r5)
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ lwzu r4,-4(r6)
+ li r3,0
+ stw r6,Globals.stack_pointer(r5)
+ stw r3,Globals.last_tail_call(r5)
+
+ if POWER601
+ sub. r10,r10,r8
+ sub r9,r9,r7
+ bge+ @no_borrow
+ addis r10,r10,hi1e9
+ addi r10,r10,lo1e9
+ subi r9,r9,1
+@no_borrow:
+ else
+ subc r10,r10,r8
+ subfe r9,r7,r9
+ endif
+
+ lwz r8,FunctionProfile.time_lo(r4)
+ lwz r7,FunctionProfile.time_hi(r4)
+
+ if POWER601
+ add r8,r8,r10
+ add r7,r7,r9
+
+ subis r9,r8,hi1e9
+ cmpwi 0,r9,lo1e9
+
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+
+ blt+ @no_carry
+
+ subi r8,r9,lo1e9
+ addi r7,r7,1
+
+@no_carry:
+ else
+ addc r8,r8,r10
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+ adde r7,r7,r9
+ endif
+
+ addi r6,r6,1
+ stw r7,FunctionProfile.time_hi(r4)
+ stw r8,FunctionProfile.time_lo(r4)
+ stw r6,FunctionProfile.n_profiler_calls(r4)
+
+ if ALLOCATION_PROFILE
+ lwz r11,Globals.n_words_free(r5)
+ stw d7,Globals.n_words_free(r5)
+ lwz r12,FunctionProfile.n_words_allocated(r4)
+ sub r11,r11,d7
+ add r12,r12,r11
+ stw r12,FunctionProfile.n_words_allocated(r4)
+ endif
+
+@store_clock:
+ time_hi r9
+ stw r9,Globals.time_hi(r5)
+ time_lo r10
+ time_hi r4
+ stw r10,Globals.time_lo(r5)
+ cmpw 0,r4,r9
+ beqlr+
+
+ b @store_clock
+
+ csect .profile_l
+profile_l:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne @use_tail_calling_function
+
+ lwz r3,-4(r6)
+@c_use_tail_calling_function:
+
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ lwz r6,FunctionProfile.n_curried_calls(r4)
+ mtlr r0
+ addi r6,r6,1
+ stw r6,FunctionProfile.n_curried_calls(r4)
+ b profile_n_
+
+@use_tail_calling_function:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b @c_use_tail_calling_function
+
+ csect .profile_l2
+profile_l2:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne @use_tail_calling_function
+
+ lwz r3,-4(r6)
+@c_use_tail_calling_function:
+
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+
+ lwz r6,FunctionProfile.n_curried_calls(r4)
+ mtlr r0
+ addi r6,r6,1
+ stw r6,FunctionProfile.n_curried_calls(r4)
+ b profile_n_
+
+@use_tail_calling_function:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b @c_use_tail_calling_function
+
+ csect .profile_n
+profile_n:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne @use_tail_calling_function
+
+ lwz r3,-4(r6)
+@c_use_tail_calling_function:
+
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+
+ lwz r6,FunctionProfile.n_lazy_calls(r4)
+ mtlr r0
+ addi r6,r6,1
+ stw r6,FunctionProfile.n_lazy_calls(r4)
+ b profile_n_
+
+@use_tail_calling_function:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b @c_use_tail_calling_function
+
+ csect .profile_n2
+profile_n2:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne @use_tail_calling_function
+
+ lwz r3,-4(r6)
+@c_use_tail_calling_function:
+
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+
+ lwz r6,FunctionProfile.n_lazy_calls(r4)
+ mtlr r0
+ addi r6,r6,1
+ stw r6,FunctionProfile.n_lazy_calls(r4)
+ b profile_n_
+
+@use_tail_calling_function:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b @c_use_tail_calling_function
+
+ csect .profile_s2
+profile_s2:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne @use_tail_calling_function
+
+ lwz r3,-4(r6)
+@c_use_tail_calling_function:
+
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ b profile_s_
+
+@use_tail_calling_function:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b @c_use_tail_calling_function
+
+ csect .profile_s
+profile_s:
+@read_clock:
+ time_hi r9
+ time_lo r10
+ time_hi r4
+ cmpw 0,r4,r9
+ bne- @read_clock
+
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r3,Globals.last_tail_call(r5)
+ lwz r6,Globals.stack_pointer(r5)
+ cmpwi 0,r3,0
+
+ lwz r7,Globals.time_hi(r5)
+ lwz r8,Globals.time_lo(r5)
+
+ bne use_tail_calling_function0
+
+ lwz r3,-4(r6)
+c_use_tail_calling_function0:
+
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+
+profile_s_:
+ lwz r6,FunctionProfile.n_strict_calls(r4)
+ mtlr r0
+ addi r6,r6,1
+ stw r6,FunctionProfile.n_strict_calls(r4)
+
+profile_n_:
+ if POWER601
+ sub. r10,r10,r8
+ sub r9,r9,r7
+ bge+ @no_borrow
+ addis r10,r10,hi1e9
+ addi r10,r10,lo1e9
+ subi r9,r9,1
+@no_borrow:
+ else
+ subc r10,r10,r8
+ subfe r9,r7,r9
+ endif
+
+ lwz r8,FunctionProfile.time_lo(r3)
+ lwz r7,FunctionProfile.time_hi(r3)
+
+ if POWER601
+ add r8,r8,r10
+ add r7,r7,r9
+
+ subis r9,r8,hi1e9
+ cmpwi 0,r9,lo1e9
+
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+
+ blt+ @no_carry
+
+ subi r8,r9,lo1e9
+ addi r7,r7,1
+
+@no_carry:
+ else
+ addc r8,r8,r10
+ lwz r6,FunctionProfile.n_profiler_calls(r4)
+ adde r7,r7,r9
+ endif
+ addi r6,r6,1
+ stw r7,FunctionProfile.time_hi(r3)
+ stw r8,FunctionProfile.time_lo(r3)
+ stw r6,FunctionProfile.n_profiler_calls(r4)
+
+ if ALLOCATION_PROFILE
+ lwz r11,Globals.n_words_free(r5)
+ stw d7,Globals.n_words_free(r5)
+ lwz r12,FunctionProfile.n_words_allocated(r3)
+ sub r11,r11,d7
+ add r12,r12,r11
+ stw r12,FunctionProfile.n_words_allocated(r3)
+ endif
+
+@store_clock:
+ time_hi r9
+ stw r9,Globals.time_hi(r5)
+ time_lo r10
+ time_hi r4
+ stw r10,Globals.time_lo(r5)
+ cmpw 0,r4,r9
+ beqctr+
+
+ b @store_clock
+
+use_tail_calling_function0:
+ li r12,0
+ stw r12,Globals.last_tail_call(r5)
+ b c_use_tail_calling_function0
+
+allocate_function_profile_record:
+ lwz r6,Globals.n_free_records_in_block(r5)
+ lwz r4,Globals.last_allocated_block(r5)
+ cmpwi 0,r6,0
+ bne+ no_alloc
+
+ stw r0,-4(sp)
+ stw r3,-8(sp)
+ stw r9,-12(sp)
+ stw r10,-16(sp)
+ mfctr r11
+ stw r11,-20(sp)
+ mflr r12
+ stw r12,-24(sp)
+
+ if USE_TEMPORARY_MEMORY
+ li r3,(128*FunctionProfile)+4
+ else
+ li r3,128*FunctionProfile
+ endif
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+32+28)(sp)
+ else
+ stwu sp,-(64+32)(sp)
+ endif
+ if USE_TEMPORARY_MEMORY
+ bl allocate_temp_memory_handle
+ else
+ bl .NewPtr
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64+32
+ endif
+ and. r4,r3,r3
+
+ lwz r12,-24(sp)
+ lwz r11,-20(sp)
+ mtlr r12
+ lwz r10,-16(sp)
+ mtctr r11
+ lwz r9,-12(sp)
+ lwz r3,-8(sp)
+ lwz r0,-4(sp)
+
+ lea r5,profile_globals
+
+ beq profiler_memory_error
+
+ if USE_TEMPORARY_MEMORY
+ lwz r6,Globals.temp_handle_list(r5)
+ stw r4,Globals.temp_handle_list(r5)
+ lwz r4,0(r4)
+ stw r6,0(r4)
+ addi r4,r4,4
+ endif
+ li r6,128
+ stw r4,Globals.last_allocated_block(r5)
+
+no_alloc:
+ subi r6,r6,1
+ stw r6,Globals.n_free_records_in_block(r5)
+ addi r7,r4,FunctionProfile
+ stw r7,Globals.last_allocated_block(r5)
+
+ lwz r6,Globals.profile_records(r5)
+ li r8,0
+ stw r8,FunctionProfile.time_hi(r4)
+ stw r8,FunctionProfile.time_lo(r4)
+ stw r8,FunctionProfile.n_profiler_calls(r4)
+ stw r8,FunctionProfile.n_strict_calls(r4)
+ stw r8,FunctionProfile.n_lazy_calls(r4)
+ stw r8,FunctionProfile.n_curried_calls(r4)
+ stw r8,FunctionProfile.n_words_allocated(r4)
+ stw r6,FunctionProfile.next(r4)
+ stw r4,Globals.profile_records(r5)
+ stw r3,FunctionProfile.name(r4)
+
+ stw r4,0(r3)
+ blr
+
+ csect .write_profile_information
+write_profile_information:
+ lea o0,profile_file_name
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .create_profile_file_name
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,4
+ else
+ lwz r0,64(sp)
+ addi sp,sp,68
+ endif
+ mtlr r0
+
+ lea d3,new_file_creator
+ li d5,'T'*256+'I'
+ lwz d4,0(d3)
+ addis d5,d5,'P'*256+'R'
+ stw d5,0(d3)
+
+ li d0,1
+ lea a0,profile_file_name
+
+ mflr r0
+ stwu r0,-4(sp)
+ bl openF
+ mtlr r0
+
+ stw d4,0(d3)
+
+ cmpwi 0,d2,0
+ beq cannot_open
+
+ mflr r0
+ li d3,0
+ stw r0,-4(sp)
+ stwu d3,-8(sp)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ stw d3,64(sp)
+ li r3,'u'*256+'t'
+ addi r4,sp,64
+ addis r3,r3,'c'*256+'p'
+ bl .Gestalt
+ nop
+
+ lwz d2,64(sp)
+ stwu r0,-4(sp)
+ bl writeFI_space
+ mtlr r0
+
+ stw d3,64(sp)
+ li r3,'l'*256+'k'
+ addi r4,sp,64
+ addis r3,r3,'p'*256+'c'
+ bl .Gestalt
+ nop
+
+ lwz d2,64(sp)
+ stwu r0,-4(sp)
+ bl writeFI_space
+ mtlr r0
+
+ stw d3,64(sp)
+ li r3,'l'*256+'k'
+ addi r4,sp,64
+ addis r3,r3,'b'*256+'c'
+ bl .Gestalt
+ nop
+
+ lwz d2,64(sp)
+ stwu r0,-4(sp)
+ bl writeFI
+ mtlr r0
+
+ li d2,13
+ stwu r0,-4(sp)
+ bl writeFC
+ mtlr r0
+
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+
+ lea d2,profile_globals
+ lwz d2,Globals.profile_records(d2)
+
+write_profile_lp:
+ cmpwi 0,d2,0
+ beq end_list
+
+ lwz d3,FunctionProfile.name(d2)
+ stwu d2,-4(sp)
+
+#if MODULE_NAMES
+ stwu d3,-4(sp)
+
+ lwz d3,-4(d3)
+ lwz d2,0(d3)
+ addi d3,d3,3
+
+write_module_name_lp:
+ subic. d2,d2,1
+ blt end_module_name
+
+ stw d2,-4(sp)
+ lbzu d2,1(d3)
+
+ mflr r0
+
+ stw d3,-8(sp)
+
+ stwu r0,-12(sp)
+ bl writeFC
+ mtlr r0
+
+ lwz d2,4(sp)
+ lwz d3,0(sp)
+ addi sp,sp,8
+ b write_module_name_lp
+
+end_module_name:
+ li d2,' '
+
+ mflr r0
+ stwu r0,-4(sp)
+ bl writeFC
+ mtlr r0
+
+ lwz d3,0(sp)
+ addi sp,sp,4
+#endif
+
+ addi d3,d3,3
+
+write_function_name_lp:
+ lbzu d2,1(d3)
+ cmpwi 0,d2,0
+ beq end_function_name
+
+ stw d3,-4(sp)
+
+ mflr r0
+ stwu r0,-8(sp)
+ bl writeFC
+ mtlr r0
+
+ lwz d3,0(sp)
+ addi sp,sp,4
+ b write_function_name_lp
+
+end_function_name:
+ li d2,' '
+
+ mflr r0
+ stwu r0,-4(sp)
+ bl writeFC
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.n_strict_calls(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.n_lazy_calls(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.n_curried_calls(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.n_profiler_calls(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.n_words_allocated(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.time_hi(d2)
+ stwu r0,-4(sp)
+ bl writeFI_space
+
+ lwz d2,0(sp)
+ lwz d2,FunctionProfile.time_lo(d2)
+ stwu r0,-4(sp)
+ bl writeFI
+
+ li d2,13
+ stwu r0,-4(sp)
+ bl writeFC
+ mtlr r0
+
+ lwz d2,0(sp)
+ addi sp,sp,4
+ lwz d2,FunctionProfile.next(d2)
+ b write_profile_lp
+
+writeFI_space:
+ mflr r0
+ stwu r0,-4(sp)
+ bl writeFI
+ mtlr r0
+
+ li d2,' '
+ b writeFC
+
+end_list:
+ mflr r0
+ stwu r0,-4(sp)
+ bl closeF
+ mtlr r0
+
+cannot_open:
+
+ if USE_TEMPORARY_MEMORY
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(96+28)(sp)
+ else
+ stwu sp,-96(sp)
+ endif
+ stw r0,96-4(sp)
+ lea r5,profile_globals
+ lwz r3,Globals.profile_stack_handle(r5)
+ bl free_temp_memory_handle
+
+ lea r5,profile_globals
+
+ stw r31,96-8(sp)
+
+ lwz r31,Globals.temp_handle_list(r5)
+ b free_temp_handles
+
+free_temp_handles_lp:
+ mr r3,r31
+ lwz r31,0(r31)
+ lwz r31,0(r31)
+ bl free_temp_memory_handle
+
+free_temp_handles:
+ cmpwi 0,r31,0
+ bne free_temp_handles_lp
+
+ lwz r31,96-8(sp)
+
+ lwz r0,96-4(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,96
+ endif
+ mtlr r0
+ endif
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .write_profile_stack
+write_profile_stack:
+ mflr r0
+ lea d0,profile_globals
+ stwu r0,-4(sp)
+ lwz d0,Globals.stack_pointer(d0)
+
+ cmpwi 0,d0,0
+ beq @stack_not_initialised
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ lea o0,stack_trace_string
+ bl .er_print_string
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+ if 1
+ li d2,12
+ else
+ li d2,24
+ endif
+@write_functions_on_stack
+ lwzu d1,-4(d0)
+ cmpwi 0,d1,0
+ beq @end_profile_stack
+
+ lwz o0,FunctionProfile.name(d1)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ addi o0,o0,4
+ bl .er_print_string
+ nop
+ li o0,13
+ bl .er_print_char
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+ subic. d2,d2,1
+ if 0
+ b @write_functions_on_stack
+ else
+ bne @write_functions_on_stack
+ endif
+
+@end_profile_stack:
+@stack_not_initialised:
+ lwz r0,0(sp)
+ mtlr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ csect .init_profiler
+init_profiler:
+ if 0
+ mflr r0
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+
+ bl .Debugger
+ nop
+
+ lwz r0,64-4(sp)
+ addi sp,sp,64
+ mtlr r0
+ endif
+
+ mflr r0
+ stwu r0,-4(sp)
+
+ if MACOSX
+ subi sp,sp,8
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-72(sp)
+ endif
+ li r3,0
+ addi r4,sp,64
+ stw r3,64(sp)
+ li r3,'u'*256+'t'
+ addis r3,r3,'c'*256+'p'
+ bl .Gestalt
+ nop
+ lwz r3,64(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ addi sp,sp,8
+ else
+ addi sp,sp,72
+ endif
+
+ cmpwi 0,r3,257
+ if POWER601
+ bne init_profiler_error1
+ else
+ beq init_profiler_error1
+ endif
+
+ if 1
+ lea r3,stack_size
+ lwz r3,0(r3)
+ else
+ li r3, (512*1024) % 65536
+ addis r3,r3,(512*1024) / 65536
+ endif
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if USE_TEMPORARY_MEMORY
+ bl allocate_temp_memory_handle
+ else
+ bl .NewPtr
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ lea r5,profile_globals
+
+ and. r9,r3,r3
+ beq init_profiler_error
+
+ if USE_TEMPORARY_MEMORY
+ stw r9,Globals.profile_stack_handle(r5)
+ lwz r9,0(r9)
+ li r0,0
+ stw r0,Globals.temp_handle_list(r5)
+ endif
+ if CHECK_STACK_OVERFLOWS
+ if 1
+ lea r3,stack_size
+ lwz r3,0(r3)
+ else
+ li r3, (512*1024) % 65536
+ addis r3,r3,(512*1024) / 65536
+ endif
+ add r3,r3,r9
+ stw r3,Globals.end_profile_stack(r5)
+ endif
+ lea r3,start_string
+ bl allocate_function_profile_record
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ li r0,0
+ stw r4,4(r9)
+ stw r0,0(r9)
+ addi r9,r9,8
+ stw r9,Globals.stack_pointer(r5)
+ stw r0,Globals.last_tail_call(r5)
+ stw d7,Globals.n_words_free(r5)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+
+@store_clock:
+ time_hi r9
+ stw r9,Globals.time_hi(r5)
+ time_lo r10
+ time_hi r4
+ stw r10,Globals.time_lo(r5)
+ cmpw 0,r4,r9
+ beqlr+
+
+ b @store_clock
+
+ if USE_TEMPORARY_MEMORY
+allocate_temp_memory_handle:
+ mflr r0
+ stw r31,-4(sp)
+ stw r0,8(sp)
+ stwu sp,-96(sp)
+
+ addi r4,sp,56
+ bl .TempNewHandle
+ nop
+
+ mr. r31,r3
+ beq return_r31
+
+ addi r4,sp,56
+ bl .TempHLock
+ nop
+
+ lha r0,56(sp)
+ cmpwi r0,0
+ beq+ return_r31
+
+ mr r3,r31
+ addi r4,sp,56
+ bl .TempDisposeHandle
+ nop
+
+ li r31,0
+return_r31:
+ lwz r0,104(sp)
+ mr r3,r31
+ mtlr r0
+ addi sp,sp,96
+ lwz r31,-4(sp)
+ blr
+
+free_temp_memory_handle:
+ mflr r0
+ stw r3,-4(sp)
+ stw r0,8(sp)
+ stwu sp,-96(sp)
+
+ addi r4,sp,56
+ bl .TempHUnlock
+ nop
+
+ lwz r3,96-4(sp)
+ addi r4,sp,56
+ bl .TempDisposeHandle
+ nop
+
+ lwz r0,104(sp)
+ addi sp,sp,96
+ mtlr r0
+ blr
+ endif
+
+init_profiler_error1:
+ lea o0,wrong_processor
+ lea r5,profile_globals
+ li r4,0
+ stw r4,Globals.stack_pointer(r5)
+ b print_error
+init_profiler_error:
+ lea o0,not_enough_memory_for_profile_stack
+ lea r5,profile_globals
+ li r4,0
+ stw r4,Globals.stack_pointer(r5)
+ b print_error
+profiler_memory_error:
+ lea o0,not_enough_memory_for_profiler
+ b print_error
+ if CHECK_STACK_OVERFLOWS
+profile_stack_overflow:
+ mflr r0
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+
+ bl .Debugger
+ nop
+
+ lwz r0,64-4(sp)
+ addi sp,sp,64
+ mtlr r0
+ b profile_stack_overflow
+ endif
+
+
+ csect data{RW}
+Globals: record
+n_free_records_in_block:ds.l 1 ; 0 n free records in block
+last_allocated_block: ds.l 1 ; 4 latest allocated block
+profile_records: ds.l 1 ; 8 profile record list
+time_hi: ds.l 1 ; 12 clock
+time_lo: ds.l 1
+stack_pointer: ds.l 1 ; 20 stack pointer
+last_tail_call ds.l 1 ; 24 last tail calling function
+n_words_free: ds.l 1
+ if USE_TEMPORARY_MEMORY
+temp_handle_list ds.l 1
+profile_stack_handle ds.l 1
+ endif
+ if CHECK_STACK_OVERFLOWS
+end_profile_stack ds.l 1
+ endif
+ endr
+
+ align 2
+profile_globals: ds Globals
+
+profile_file_name:
+ dc.l __STRING__+2
+ dc.l 0
+ ds.b 32
+ align 2
+ if MODULE_NAMES
+m_system:
+ dc.l 6
+ dc.b 'System'
+ dc.b 0,0
+ dc.l m_system
+ endif
+start_string:
+ dc.l 0
+ dc.b 'start'
+ dc.b 0
+ align 2
+not_enough_memory_for_profile_stack:
+ dc.b 'not enough memory for profile stack'
+ dc.b 13
+ dc.b 0
+not_enough_memory_for_profiler:
+ dc.b 'not enough memory for profiler'
+ dc.b 13
+ dc.b 0
+wrong_processor:
+ if POWER601
+ dc.b 'Not a PowerPC601 processor (don''t use profiling option for 601)'
+ else
+ dc.b 'This is a PowerPC601 processor (use profiling option for 601)'
+ endif
+ dc.b 13
+ dc.b 0
+stack_trace_string:
+ dc.b 'Stack trace:'
+ dc.b 13
+ dc.b 0
+ align 2
+
+ macro
+ te &address
+ tc &address{TC},&address
+ endm
+
+ toc
+
+ te profile_globals
+ te profile_file_name
+ te not_enough_memory_for_profile_stack
+ te not_enough_memory_for_profiler
+ te wrong_processor
+ te start_string
+ te stack_trace_string
+ te new_file_creator
+ te stack_size
diff --git a/pstartup.a b/pstartup.a
new file mode 100644
index 0000000..49a1dd8
--- /dev/null
+++ b/pstartup.a
@@ -0,0 +1,6085 @@
+;
+; File: pstartup.a
+; Author: John van Groningen
+; Machine: power macintosh
+
+ string asis
+
+ macro
+ setmbit &vector,&bit_n,&byte_offset,&bit,&byte,&scratch,&shift
+ rlwinm &byte_offset,&bit_n,32-&shift-3,3+&shift,31
+ lbzx &byte,&vector,&byte_offset
+ rlwinm &scratch,&bit_n,(32-&shift) & 31,29,31
+ srw &bit,g3,&scratch
+ or &byte,&byte,&bit
+ stbx &byte,&vector,&byte_offset
+ endm
+
+ macro
+ tstmbit &vector,&bit_n,&byte_offset,&bit,&byte,&bit_n_in_byte,&shift
+ rlwinm &byte_offset,&bit_n,32-&shift-3,3+&shift,31
+ lbzx &byte,&vector,&byte_offset
+ rlwinm &bit_n_in_byte,&bit_n,32-&shift,29,31
+ rlwnm. &bit,&byte,&bit_n_in_byte,24,24
+ endm
+
+ macro
+ clrmbit &vector,&bit_n,&byte_offset,&bit,&byte,&scratch,&shift
+ rlwinm &byte_offset,&bit_n,32-&shift-3,3+&shift,31
+ lbzx &byte,&vector,&byte_offset
+ rlwinm &scratch,&bit_n,32-&shift,29,31
+ srw &bit,g3,&scratch
+ andc &byte,&byte,&bit
+ stbx &byte,&vector,&byte_offset
+ endm
+
+ include 'pmacros.a'
+
+d0: set r24
+d1: set r25
+d2: set r26
+d3: set r27
+d4: set r28
+d5: set r29
+d6: set r30
+d7: set r31
+
+a0: set r23
+a1: set r22
+a2: set r21
+a3: set r20
+a4: set r19
+a5: set r18
+a6: set r17
+
+o0: set r3
+o1: set r4
+o2: set r5
+o3: set r6
+o4: set r7
+o5: set r8
+
+g2: set r9
+g3: set r10
+
+g0: set r11
+g1: set r12
+
+int_reg set r16
+char_reg set r15
+real_reg set r14
+bool_reg set r13
+
+MACOSX set 1
+
+SHARE_CHAR_INT set 1
+MY_ITOS set 1
+FINALIZERS set 1
+MEASURE_GC set 0
+
+COPIED_VECTOR set 1
+USE_DCBZ set 0
+COMPACT_GC_ONLY set 0
+
+ADJUST_HEAP_SIZE set 1
+MARK_GC set 1
+MARK_AND_COPY_GC set 1
+
+ if LINUX
+STDERR_TO_FILE set 0
+WRITE_HEAP set 0
+ else
+WRITE_HEAP set 1
+STDERR_TO_FILE set 1
+ endif
+;PROFILE set 1
+UNBOXED_CLOSURES set 1
+
+MODULE_NAMES_IN_TIME_PROFILER set 1
+
+EXCEPTIONS set 0
+
+MINIMUM_HEAP_SIZE set 8000
+
+ if 1
+DESCRIPTOR_ARITY_OFFSET set (-2)
+ZERO_ARITY_DESCRIPTOR_OFFSET set (-8)
+ else
+DESCRIPTOR_ARITY_OFFSET set (-8)
+ZERO_ARITY_DESCRIPTOR_OFFSET set (-12)
+ endif
+
+ export r_to_i_buffer
+ comm r_to_i_buffer,8
+ comm heap_mbp,4
+ comm heap_p,4
+ comm heap_p1,4
+ comm heap_p2,4
+ comm heap_size_33,4
+ if COPIED_VECTOR
+ comm heap_size_129,4
+ comm heap_copied_vector,4
+ comm heap_copied_vector_size,4
+ comm heap_end_after_copy_gc,4
+ endif
+ comm extra_heap,4
+ comm extra_heap_size,4
+ comm stack_p,4
+ if MACOSX
+ comm end_a_stack,4
+ comm end_b_stack,4
+ endif
+ comm halt_sp,4
+; number of long words requested from the garbage collector
+ comm alloc_size,4
+ comm basic_only,4
+ comm last_time,4
+ comm execute_time,4
+ comm garbage_collect_time,4
+ comm IO_time,4
+ if MEASURE_GC
+ comm compact_garbage_collect_time,4
+ comm mark_compact_garbage_collect_time,4
+ endif
+ export saved_heap_p
+ comm saved_heap_p,8
+
+ export saved_a_stack_p
+ comm saved_a_stack_p,4
+
+ comm sprintf_buffer,32
+ comm sprintf_time_buffer,20
+
+ export small_integers
+ comm small_integers,33*8
+ export static_characters
+ comm static_characters,256*8
+
+ if EXCEPTIONS
+ comm exception_info,12
+ endif
+
+ comm caf_list,4
+ export caf_listp
+ comm caf_listp,4
+
+ csect data{RW}
+
+heap_p3: dc.l 0
+heap_vector:dc.l 0
+heap_end_after_gc: dc.l 0
+
+ if MARK_GC
+bit_counter:
+ dc.l 0
+bit_vector_p:
+ dc.l 0
+zero_bits_before_mark:
+ dc.l 1
+free_after_mark:
+ dc.l 1000
+last_heap_free:
+ dc.l 0
+lazy_array_list:
+ dc.l 0
+ if ADJUST_HEAP_SIZE
+bit_vector_size:
+ dc.l 0 ; in bits
+ endif
+ endif
+
+ align 2
+zero_length_string:
+ dc.l __STRING__+2
+ dc.l 0
+true_string:
+ dc.l __STRING__+2
+ dc.l 4
+true_c_string:
+ dc.b 'True'
+ dc.b 0,0,0,0
+false_string:
+ dc.l __STRING__+2
+ dc.l 5
+false_c_string:
+ dc.b 'False'
+ dc.b 0,0,0
+file_c_string:
+ dc.b 'File'
+ dc.b 0,0,0,0
+
+; -1: compact or mark, no extra heap
+; 0: copy, no extra heap
+; 1: compact, extra heap
+; 2: copy, extra heap
+garbage_collect_flag:
+ dc.b 0
+ dc.b 0,0,0
+
+out_of_memory_string_1:
+ dc.b 'Not enough memory to allocate heap and stack'
+ dc.b 13,0
+printf_int_string:
+ dc.b '%d'
+ dc.b 0
+printf_real_string:
+ dc.b '%g'
+ dc.b 0
+printf_string_string:
+ dc.b '%s'
+ dc.b 0
+printf_char_string:
+ dc.b '%c'
+ dc.b 0
+garbage_collect_string_1:
+ dc.b 'A stack: '
+ dc.b 0
+garbage_collect_string_2:
+ dc.b ' bytes. BC stack: '
+ dc.b 0
+garbage_collect_string_3:
+ dc.b ' bytes.'
+ dc.b 13,0
+heap_use_after_gc_string_1:
+ dc.b 'Heap use after garbage collection: '
+ dc.b 0
+heap_use_after_gc_string_2:
+ dc.b ' Bytes.'
+ dc.b 13,0
+stack_overflow_string:
+ dc.b 'Stack overflow.'
+ dc.b 13,0
+out_of_memory_string_4:
+ dc.b 'Heap full.'
+ dc.b 13,0
+time_string_1:
+ dc.b 'Execution: '
+ dc.b 0
+time_string_2:
+ dc.b ' Garbage collection: '
+ dc.b 0
+ if MEASURE_GC
+time_string_2a:
+ dc.b ' '
+ dc.b 0
+ endif
+time_string_3:
+ dc.b ' IO: '
+ dc.b 0
+time_string_4:
+ dc.b ' Total: '
+ dc.b 0
+high_index_string:
+ dc.b 'Index too high in UPDATE string.'
+ dc.b 13,0
+low_index_string:
+ dc.b 'Index negative in UPDATE string.'
+ dc.b 13,0
+IO_error_string:
+ dc.b 'IO error: '
+ dc.b 0
+new_line_string:
+ dc.b 13,0
+
+sprintf_time_string:
+ dc.b '%d.%02d'
+ dc.b 0
+
+ if MARK_GC
+marked_gc_string_1:
+ dc.b 'Marked: '
+ dc.b 0
+ endif
+ if PROFILE
+ align 2
+ if MODULE_NAMES_IN_TIME_PROFILER
+m_system:
+ dc.l 6
+ dc.b 'System'
+ dc.b 0,0
+ dc.l m_system
+ endif
+garbage_collector_name:
+ dc.l 0
+ dc.b 'garbage_collector'
+ dc.b 0
+ align 2
+ endif
+ if WRITE_HEAP
+ comm heap2_begin_and_end,8
+ endif
+
+ align 3
+entier_constants_and_buffers:
+ dc.d "0.0"
+ dc.d "0.0"
+ dc.l 0x43300000
+ dc.l 0x00000000
+ dc.l 0x43300000
+ dc.l 0x80000000
+
+ if FINALIZERS
+ import __Nil
+ import e____system__kFinalizer
+ import e____system__kFinalizerGCTemp
+ export finalizer_list
+ comm finalizer_list,4
+ export free_finalizer_list
+ comm free_finalizer_list,4
+ endif
+
+ align 1
+
+ csect text{PR}
+ if LINUX
+ export abc_main
+ else
+ export .abc_main
+ endif
+ export print_
+ export print_char
+ export print_int
+ export print_real
+ export print_sc
+ export print_symbol
+ export print_symbol_sc
+ export print__string__
+ export print__chars__sc
+ export printD
+
+ export eprint__
+ export eprint__string__
+ export eprintD
+
+ export push_t_r_args
+ export push_a_r_args
+ export halt
+
+ export catAC
+ export sliceAC
+ export updateAC
+ export eqAC
+ export cmpAC
+
+ export string_to_string_node
+
+ export create_array
+ export create_arrayB
+ export create_arrayC
+ export create_arrayI
+ export create_arrayR
+ export create_R_array
+
+ export _create_arrayB
+ export _create_arrayC
+ export _create_arrayI
+ export _create_arrayR
+ export _create_r_array
+
+ export BtoAC
+ export DtoAC
+ export ItoAC
+ export RtoAC
+ export eqD
+
+ export collect_0,collect_1,collect_2,collect_3
+ export collect_00,collect_01,collect_02,collect_03
+
+ export eval_01,eval_11,eval_02,eval_12,eval_22
+
+ import e__system__AP
+
+ export e__system__sAP
+ export yet_args_needed,yet_args_needed_0,yet_args_needed_1
+ export yet_args_needed_2,yet_args_needed_3,yet_args_needed_4
+
+ export _c3,_c4,_c5,_c6,_c7,_c8,_c9,_c10,_c11,_c12
+ export _c13,_c14,_c15,_c16,_c17,_c18,_c19,_c20,_c21,_c22
+ export _c23,_c24,_c25,_c26,_c27,_c28,_c29,_c30,_c31,_c32
+
+ export __indirection,__eaind,eval_fill
+ export eval_upd_0,eval_upd_1,eval_upd_2,eval_upd_3,eval_upd_4
+ export eval_upd_5,eval_upd_6,eval_upd_7,eval_upd_8,eval_upd_9
+ export eval_upd_10,eval_upd_11,eval_upd_12,eval_upd_13,eval_upd_14
+ export eval_upd_15,eval_upd_16,eval_upd_17,eval_upd_18,eval_upd_19
+ export eval_upd_20,eval_upd_21,eval_upd_22,eval_upd_23,eval_upd_24
+ export eval_upd_25,eval_upd_26,eval_upd_27,eval_upd_28,eval_upd_29
+ export eval_upd_30,eval_upd_31,eval_upd_32
+
+ export repl_args_b
+ export push_arg_b
+ export del_args
+ if 0
+ export o__S_P2
+ export ea__S_P2
+ endif
+ export .add_IO_time
+ export .add_execute_time
+
+ export .IO_error
+ export print_error
+ export stack_overflow
+
+ export out_of_memory_4
+
+ export acos_real
+ export asin_real
+ export atan_real
+ export cos_real
+ export sin_real
+ export tan_real
+ export ln_real
+ export log10_real
+ export exp_real
+ export sqrt_real
+ export pow_real
+ export entier_real
+ if LINUX
+ else
+ export .my_pointer_glue{PR}
+ endif
+ if EXCEPTIONS
+ export e__Exceptions__scatch__exception
+ export e__Exceptions__sraise__exception
+ endif
+ if LINUX
+ import __start
+ else
+ import _start
+ endif
+ export __driver
+
+
+; from system.abc:
+ import INT
+ import CHAR
+ import BOOL
+ import REAL
+ import __STRING<='STRING'
+ import FILE
+ import __STRING__
+ import __ARRAY__
+ import __cycle__in__spine
+ import __print__graph
+ import __eval__to__nf
+
+ if STDERR_TO_FILE
+ import .close_stderr_file
+ endif
+
+; from cgcon.c:
+ import .w_print_char
+ import .w_print_text
+ import .w_print_int
+ import .w_print_real
+ import .w_print_string
+
+ if STDERR_TO_FILE
+ import .er_print_char
+ import .er_print_string
+ import .er_print_int
+ import .er_print_text
+ else
+ import .ew_print_char
+ import .ew_print_string
+ import .ew_print_int
+ endif
+ if 0
+
+ import .wait_for_key_press
+ else
+ import execution_aborted
+ endif
+ import stack_size
+ import heap_size
+ import flags
+ if ADJUST_HEAP_SIZE
+ import heap_size_multiple
+ import initial_heap_size
+ endif
+
+; from standard c library:
+ import .sprintf
+ if LINUX
+ import malloc
+ import free
+ else
+ import .NewPtr
+ import .DisposePtr
+ import .TickCount
+ if 0
+ import .Debugger
+ endif
+ endif
+ import .acos
+ import .asin
+ import .atan
+ import .cos
+ import .sin
+ import .tan
+ import .log
+ import .log10
+ import .exp
+ import .sqrt
+ import .pow
+
+ if PROFILE
+ import init_profiler
+ import profile_s,profile_n,profile_r,profile_ti
+ import write_profile_information,write_profile_stack
+ endif
+
+ if LINUX
+abc_main:
+ else
+.abc_main:
+ endif
+ mflr r0
+ stwu r0,-4(sp)
+ stmw r13,-76(sp)
+ subi sp,sp,76
+
+ lea o0,flags
+ lwz d0,0(o0)
+ lea o0,basic_only
+ andi. d0,d0,1
+ stw d0,0(o0)
+
+ lea o0,heap_size
+ lwz d0,0(o0)
+ subi o0,d0,3
+ li o1,33
+ divwu o0,o0,o1
+ lea o1,heap_size_33
+ stw o0,0(o1)
+
+ if COPIED_VECTOR
+ lea o0,heap_size
+ li o1,129
+ lwz d0,0(o0)
+ subi o0,d0,7
+ divwu o0,o0,o1
+ lea o1,heap_size_129
+ stw o0,0(o1)
+ addi o0,o0,3
+ lea o1,heap_copied_vector_size
+ clrrwi o0,o0,2
+ stw o0,0(o1)
+
+ lea o1,heap_end_after_copy_gc
+ li g0,0
+ stw g0,0(o1)
+ endif
+
+ lea o1,heap_size
+ lwz o0,0(o1)
+ addi o0,o0,7
+ clrrwi o0,o0,3
+ stw o0,0(o1)
+ addi o0,o0,3+4
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+
+ if LINUX
+ bl malloc
+ else
+ bl .NewPtr
+ endif
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ cmpwi 0,o0,0
+ beq no_memory_1
+
+ lea o1,heap_mbp
+ stw o0,0(o1)
+
+ addi o0,o0,3
+ clrrwi a6,o0,2
+
+ lea o0,heap_p
+ lea o1,heap_p1
+ stw a6,0(o0)
+ stw a6,0(o1)
+ if MACOSX
+ lea o0,stack_size
+ lwz o0,0(o0)
+
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+
+ bl .NewPtr
+ nop
+
+ lwz sp,0(sp)
+
+ cmpwi 0,o0,0
+ beq no_memory_1
+
+ mr a4,o0
+ lea o0,stack_p
+ stw a4,0(o0)
+
+ lea o0,stack_size
+ addi d0,sp,128
+ lwz d1,0(o0)
+
+ lea o0,end_a_stack
+ sub d0,d0,d1
+ add d1,a4,d1
+ stw d1,0(o0)
+
+ lea o0,end_b_stack
+ stw d0,0(o0)
+ else
+ lea o0,stack_size
+ addi d0,sp,-128
+ lwz o0,0(o0)
+ sub a4,d0,o0
+
+ lea o0,stack_p
+ stw a4,0(o0)
+ endif
+ lea a0,small_integers
+ li d0,0
+ lea d1,INT2
+make_small_integers_lp:
+ stw d1,0(a0)
+ stw d0,4(a0)
+ addi d0,d0,1
+ cmpwi 0,d0,33
+ addi a0,a0,8
+ bne make_small_integers_lp
+
+ lea a0,static_characters
+ li d0,0
+ lea d1,CHAR2
+make_static_characters_lp:
+ stw d1,0(a0)
+ stw d0,4(a0)
+ addi d0,d0,1
+ cmpwi 0,d0,256
+ addi a0,a0,8
+ bne make_static_characters_lp
+
+ lea o0,caf_listp
+ if LINUX
+ lea a0,caf_list+4
+ else
+ lea a0,caf_list4
+ endif
+ stw a0,0(o0)
+ li g0,0
+ stw g0,-4(a0)
+
+ if FINALIZERS
+ lea o0,finalizer_list
+ lea o1,free_finalizer_list
+ lea a0,__Nil_m8
+ stw a0,0(o0)
+ stw a0,0(o1)
+ endif
+
+ if COPIED_VECTOR
+ lea o0,heap_size_129
+ lwz d1,0(o0)
+ slwi d7,d1,6-2
+ slwi d1,d1,6
+ lea o0,heap_copied_vector
+ add d0,a6,d1
+ lea o1,heap_copied_vector_size
+ stw d0,0(o0)
+ lwz o1,0(o1)
+ lea o0,heap_p2
+ add d0,d0,o1
+ stw d0,0(o0)
+ else
+ lea o0,heap_size
+ lwz d1,0(o0)
+ lea o0,heap_p2
+ srwi d1,d1,1
+ add d0,a6,d1
+ srwi d7,d1,2
+ stw d0,0(o0)
+ endif
+
+ lea o0,garbage_collect_flag
+ li g0,0
+ stb g0,0(o0)
+
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark1
+ endif
+
+ if MARK_GC || COMPACT_GC_ONLY
+ lea o0,heap_size_33
+ lea o1,heap_vector
+ lwz d0,0(o0)
+ stw a6,0(o1)
+ slwi d7,d0,3
+ add a6,a6,d0
+ addi a6,a6,3
+ lea o0,heap_p3
+ clrrwi a6,a6,2
+ stw a6,0(o0)
+ lea o0,garbage_collect_flag
+ li d0,-1
+ stb d0,0(o0)
+ endif
+
+ if MARK_AND_COPY_GC
+no_mark1:
+ endif
+
+ if ADJUST_HEAP_SIZE
+ lea d0,initial_heap_size
+ lea o0,flags
+ lwz d0,0(d0)
+ if MARK_AND_COPY_GC
+ lwz o0,0(o0)
+ li d1,MINIMUM_HEAP_SIZE/2
+ andi. r0,o0,64
+ bne no_mark9
+ add d1,d1,d1
+no_mark9:
+ else
+ if MARK_GC || COMPACT_GC_ONLY
+ li d1,MINIMUM_HEAP_SIZE
+ else
+ li d1,MINIMUM_HEAP_SIZE/2
+ endif
+ endif
+ cmpw d0,d1
+ ble too_large_or_too_small
+ srwi d0,d0,2
+ cmpw d0,d7
+ bge too_large_or_too_small
+ mr d7,d0
+too_large_or_too_small:
+ endif
+
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark2
+ endif
+
+ if MARK_GC && ADJUST_HEAP_SIZE
+ lea o0,bit_vector_size
+ stw d7,0(o0)
+ endif
+
+ if MARK_AND_COPY_GC
+no_mark2:
+ endif
+
+ lea o0,heap_end_after_gc
+ slwi d0,d7,2
+ add d0,a6,d0
+ stw d0,0(o0)
+
+ lea o0,halt_sp
+ stw sp,0(o0)
+
+ if EXCEPTIONS
+ lea o0,exception_info
+ li o1,0
+ stw o1,0(o0)
+ endif
+ bl _init_timer
+
+
+ lea a5,__cycle__in__spine
+ lea int_reg,INT2
+ lea char_reg,CHAR2
+ lea real_reg,REAL2
+ lea bool_reg,BOOL2
+
+ if USE_DCBZ
+ subi d7,d7,15
+ li g2,32
+ endif
+
+ li r0,-1
+ if PROFILE
+ stwu r0,-4(sp)
+ bl init_profiler
+ endif
+ stwu r0,-4(sp)
+
+ if 0
+ stwu sp,-64(sp)
+ bl .Debugger
+ nop
+ addi sp,sp,64
+ endif
+
+ subi a6,a6,4
+
+ if LINUX
+ bl __start
+ else
+ bl _start
+ endif
+ nop
+
+exit:
+ bl .add_execute_time
+
+ lea o0,flags
+ lwz d0,0(o0)
+ andi. g0,d0,8
+ beq no_print_execution_time
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+
+ lea o0,time_string_1
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+
+ lea a0,execute_time
+ lwz d0,0(a0)
+ bl _print_time
+
+ lea o0,time_string_2
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ lea a0,garbage_collect_time
+ lwz d0,0(a0)
+ bl _print_time
+
+ if MEASURE_GC
+ lea o0,time_string_2a
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ lea a0,mark_compact_garbage_collect_time
+ lwz d0,0(a0)
+ bl _print_time
+
+ lea o0,time_string_2a
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ lea a0,compact_garbage_collect_time
+ lwz d0,0(a0)
+ bl _print_time
+ endif
+
+ lea o0,time_string_3
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ lea a0,IO_time
+ lwz d0,0(a0)
+ bl _print_time
+
+ lea o0,time_string_4
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ lea a0,execute_time
+ lwz d0,0(a0)
+ lea a0,garbage_collect_time
+ lwz d2,0(a0)
+ add d0,d0,d2
+ if MEASURE_GC
+ lea a0,mark_compact_garbage_collect_time
+ lwz d2,0(a0)
+ add d0,d0,d2
+ lea a0,compact_garbage_collect_time
+ lwz d2,0(a0)
+ add d0,d0,d2
+ endif
+ lea a0,IO_time
+ lwz d2,0(a0)
+ add d0,d0,d2
+
+ bl _print_time
+
+ li o0,13
+ if STDERR_TO_FILE
+ bl .er_print_char
+ else
+ bl .ew_print_char
+ endif
+ nop
+
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+no_print_execution_time:
+
+exit_3:
+exit_2:
+ lea o0,heap_mbp
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ lwz o0,0(o0)
+ if LINUX
+ bl free
+ else
+ bl .DisposePtr
+ endif
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+exit_1:
+ if STDERR_TO_FILE
+ lea o0,flags
+ lwz d0,0(o0)
+ andi. g0,d0,128
+ beq no_close_stderr_file
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .close_stderr_file
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+no_close_stderr_file:
+ endif
+ if PROFILE
+ mflr r0
+ stwu r0,-4(sp)
+ bl write_profile_information
+ endif
+
+ lwz r0,76(sp)
+ mtlr r0
+ lmw r13,0(sp)
+ addi sp,sp,80
+ blr
+
+__driver:
+ lea o1,flags
+ lwz o0,0(o1)
+ andi. r0,o0,16
+ bne _eval__to__nf
+ b __print__graph
+_eval__to__nf:
+ b __eval__to__nf
+
+_print_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ if LINUX
+ li o1,100
+ else
+ li o1,60
+ endif
+ divwu o2,d0,o1
+
+ if LINUX
+ mulli o3,o2,100
+ sub o3,d0,o3
+ else
+ mulli o3,o2,60
+ sub o3,d0,o3
+ mulli o3,o3,5
+ li o1,3
+ divwu o3,o3,o1
+ endif
+ lea o1,sprintf_time_string
+ lea o0,sprintf_time_buffer
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .sprintf
+ nop
+
+ lea o0,sprintf_time_buffer
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ blr
+
+no_memory_1:
+ lea o0,out_of_memory_string_1
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ b exit_1
+
+print_sc:
+ lea o0,basic_only
+ lwz o1,0(o0)
+ cmpwi 0,o1,0
+ bne end_print
+print_:
+ mr o0,d0
+
+print_string_o0_and_return:
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_string
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+end_print:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+printD: andi. r0,d0,2
+ bne printD_
+
+ mr a2,d0
+ b print_string_a2
+
+print_symbol:
+ li d1,0
+ b print_symbol_2
+
+print_symbol_sc:
+ lea o0,basic_only
+ lwz d1,0(o0)
+print_symbol_2:
+ lwz d0,0(a0)
+
+ cmpw 0,int_reg,d0
+ beq print_int_node
+
+ cmpw 0,char_reg,d0
+ beq print_char_node
+
+ cmpw 0,bool_reg,d0
+ beq print_bool
+
+ cmpw 0,real_reg,d0
+ beq print_real_node
+
+ cmpwi 0,d1,0
+ bne end_print_symbol
+
+printD_: lha d1,-2(d0)
+ addi a2,d0,-2
+
+ cmplwi 0,d1,256
+ bge print_record
+
+ slwi d1,d1,3
+ sub a2,a2,d1
+
+ lhz d1,DESCRIPTOR_ARITY_OFFSET(a2)
+ addi a2,a2,4
+ slwi d1,d1,3
+ add a2,a2,d1
+ b print_string_a2
+
+print_record:
+ lwz a2,-4(a2)
+ b print_string_a2
+
+end_print_symbol:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+print_int_node:
+ lwz o0,4(a0)
+print_int2:
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_int
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+print_int:
+ mr o0,d0
+ b print_int2
+
+print_char:
+ lea o0,basic_only
+ lwz d1,0(o0)
+ cmpwi 0,d1,0
+ bne print_char_node_bo
+
+ b print_char_node_sc
+
+print_char_node:
+ cmpwi 0,d1,0
+ lwz d0,4(a0)
+ bne print_char_node_sc
+print_char_node_bo:
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ li o0,0x27
+ bl .w_print_char
+
+ mr o0,d0
+ bl .w_print_char
+
+ li o0,0x27
+ bl .w_print_char
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+print_char_node_sc:
+ mr o0,d0
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_char
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+print_bool:
+ lbz o0,7(a0)
+ cmpwi 0,o0,0
+ beq print_false
+
+print_true:
+ lea o0,true_c_string
+ b print_string_o0_and_return
+
+print_false:
+ lea o0,false_c_string
+ b print_string_o0_and_return
+
+print_real:
+ fmr f1,f14
+ b print_real_
+print_real_node:
+ lfd f1,4(a0)
+print_real_:
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_real
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+print_string_a2:
+ lwz o1,0(a2)
+ addi o0,a2,4
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_text
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+print__chars__sc:
+ lea o0,basic_only
+ lwz d1,0(o0)
+ cmpwi 0,d1,0
+ bne no_print_chars
+
+print__string__:
+ lwz o1,4(a0)
+ addi o0,a0,8
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .w_print_text
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+no_print_chars:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .eprint__
+eprint__:
+ mr o0,d0
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+ csect .eprint__string__
+eprint__string__:
+ lwz o1,4(a0)
+ addi o0,a0,8
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if STDERR_TO_FILE
+ bl .er_print_text
+ else
+ bl .ew_print_text
+ endif
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+ csect .eprintD
+eprintD: andi. r0,d0,2
+ bne eprintD_
+
+ mr a2,d0
+ b eprint_string_a2
+
+eprintD_: lha d1,-2(d0)
+ addi a2,d0,-2
+
+ cmplwi 0,d1,256
+ bge eprint_record
+
+ slwi d1,d1,3
+ sub a2,a2,d1
+
+ lhz d1,DESCRIPTOR_ARITY_OFFSET(a2)
+ addi a2,a2,4
+ slwi d1,d1,3
+ add a2,a2,d1
+ b eprint_string_a2
+
+eprint_record:
+ lwz a2,-4(a2)
+
+eprint_string_a2:
+ lwz o1,0(a2)
+ addi o0,a2,4
+
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if STDERR_TO_FILE
+ bl .er_print_text
+ else
+ bl .ew_print_text
+ endif
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,8
+ else
+ lwz r0,64(sp)
+ addi sp,sp,72
+ endif
+ mtlr r0
+ lwz r0,-4(sp)
+ blr
+
+ csect .DtoAC
+
+DtoAC: lha d1,-2(d0)
+ addi a0,d0,-2
+
+ cmplwi 0,d1,256
+ bge DtoAC_record
+
+ slwi d1,d1,3
+ bsub a0,d1
+ if 1
+ lhz d1,DESCRIPTOR_ARITY_OFFSET(a0)
+ baddi a0,4
+ slwi d1,d1,3
+ badd a0,d1
+ endif
+DtoAC_a0:
+ lwz d2,0(a0)
+ mr a2,a0
+
+ addi d3,d2,3
+ bsubi d7,2
+
+ srwi d3,d3,2
+ sub. d7,d7,d3
+ blt DtoAC_gc
+DtoAC_r_gc:
+ lea o1,__STRING__2
+
+ subic. d3,d3,1
+
+ addi a0,a6,4
+ stw o1,4(a6)
+ stwu d2,8(a6)
+ blt DtoAC_copy
+
+DtoAC_copy_lp:
+ lwzu o0,4(a2)
+ subic. d3,d3,1
+ stwu o0,4(a6)
+ bge DtoAC_copy_lp
+DtoAC_copy:
+
+ lwz r0,0(sp)
+ baddi sp,4
+ blr
+
+DtoAC_gc: mflr r0
+ mr d0,a0
+ bl collect_0
+ mr a2,d0
+ b DtoAC_r_gc
+
+DtoAC_record:
+ lwz a0,-4(a0)
+ b DtoAC_a0
+
+ csect .push_a_r_args
+push_a_r_args:
+ lwz a1,8(a0)
+ subi a1,a1,2
+ lhz d3,0(a1)
+ subi d3,d3,256
+ lhz d1,2(a1)
+ addi a1,a1,4
+ sub d2,d3,d1
+ slwi d0,d0,2
+
+ mullw d4,d0,d3
+ addi a0,a0,12
+ add a0,a0,d4
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+
+ slwi o0,d1,2
+ add a0,a0,o0
+ mr a3,a0
+ b push_a_elements
+
+push_a_elements_lp:
+ lwzu o0,-4(a3)
+ addi a4,a4,4
+ stw o0,-4(a4)
+push_a_elements:
+ subic. d1,d1,1
+ bge push_a_elements_lp
+
+ slwi o0,d2,2
+ add a0,a0,o0
+ b push_b_elements
+
+push_b_elements_lp:
+ lwzu o0,-4(a0)
+ stwu o0,-4(sp)
+push_b_elements:
+ subic. d2,d2,1
+ bge push_b_elements_lp
+
+ mr d0,a1
+ blr
+
+push_t_r_args:
+ lwz a1,0(a0)
+ addi a0,a0,4
+ subi a1,a1,2
+ lhz d3,0(a1)
+ lhz d1,2(a1)
+ subi d3,d3,256
+ addi d0,a1,4
+ sub d2,d3,d1
+
+ slwi d4,d3,2
+ cmplwi 0,d3,2
+ add a1,a0,d4
+ ble small_record
+
+ lwz a1,4(a0)
+ subi a1,a1,4
+ add a1,a1,d4
+small_record:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ b push_r_b_elements
+
+push_r_b_elements_lp:
+ subic. d3,d3,1
+ bne not_first_arg_b
+
+ lwz o0,0(a0)
+ stwu o0,-4(sp)
+ b push_r_b_elements
+not_first_arg_b:
+ lwzu o0,-4(a1)
+ stwu o0,-4(sp)
+push_r_b_elements:
+ subic. d2,d2,1
+ bge push_r_b_elements_lp
+
+ b push_r_a_elements
+
+push_r_a_elements_lp:
+ subic. d3,d3,1
+ addi a4,a4,4
+ bne not_first_arg_a
+
+ lwz o0,0(a0)
+ stw o0,-4(a4)
+ b push_r_a_elements
+
+not_first_arg_a:
+ lwzu o0,-4(a1)
+ stw o0,-4(a4)
+push_r_a_elements:
+ subic. d1,d1,1
+ bge push_r_a_elements_lp
+
+ blr
+
+ csect .BtoAC
+BtoAC:
+ andi. d0,d0,255
+ beq BtoAC_false
+BtoAC_true:
+ lea a0,true_string
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+BtoAC_false:
+ lea a0,false_string
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .RtoAC
+RtoAC:
+ if LINUX
+ fmr f1,f14
+ else
+ stfd f14,-8(sp)
+ endif
+ lea o1,printf_real_string
+ lea o0,sprintf_buffer
+ if LINUX
+ creqv 6,6,6
+ else
+ lwz o2,-8(sp)
+ lwz o3,-4(sp)
+ endif
+ mflr r0
+ if MACOSX
+ stwu r0,-4(sp)
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+ endif
+ bl .sprintf
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ addi sp,sp,4
+ else
+ lwz r0,60(sp)
+ addi sp,sp,64
+ endif
+ mtlr r0
+
+ b return_sprintf_buffer_string
+
+ csect .ItoAC
+ItoAC:
+ if MY_ITOS
+ lea a0,sprintf_buffer
+ cmpwi 0,d0,0
+ bge no_minus
+
+ li o0,45
+ stb o0,0(a0)
+ addi a0,a0,1
+ li g0,0
+ sub d0,g0,d0
+no_minus:
+ addi a2,a0,12
+ beq zero_digit
+
+calculate_digits:
+ cmplwi 0,d0,10
+ blt last_digit
+
+ li o1,10
+ divwu o0,d0,o1
+
+ mullw a1,o0,o1
+ sub a1,d0,a1
+ addi a1,a1,48
+
+ stb a1,0(a2)
+ addi a2,a2,1
+
+ mr d0,o0
+ b calculate_digits
+
+last_digit:
+ cmpwi 0,d0,0
+ beq no_zero
+zero_digit:
+ addi d0,d0,48
+ stb d0,0(a2)
+ addi a2,a2,1
+no_zero:
+ addi a1,a0,12
+
+reverse_digits:
+ lbzu d1,-1(a2)
+ cmpw 0,a2,a1
+ stb d1,0(a0)
+ addi a0,a0,1
+ bne reverse_digits
+
+ li g0,0
+ lea d0,sprintf_buffer
+
+ stb g0,0(a0)
+ sub d0,a0,d0
+ b sprintf_buffer_to_string
+
+ else
+ mr o2,d0
+ lea o1,printf_int_string
+ lea o0,sprintf_buffer
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .sprintf
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ endif
+
+return_sprintf_buffer_string:
+ lea o0,sprintf_buffer
+ li d0,-1
+ subi o0,o0,1
+
+count_chars_in_c_string:
+ lbzu d1,1(o0)
+ addi d0,d0,1
+ cmpwi d1,0
+ bne count_chars_in_c_string
+
+ if MY_ITOS
+sprintf_buffer_to_string:
+ endif
+ addi d1,d0,3
+ srwi d1,d1,2
+ subi d7,d7,2
+ sub. d7,d7,d1
+ bge+ D_to_S_no_gc
+
+ mflr r0
+ bl collect_0
+
+D_to_S_no_gc:
+ lea a0,sprintf_buffer
+ lea o0,__STRING__2
+ addi d2,a6,4
+ stw o0,4(a6)
+ stwu d0,8(a6)
+ b D_to_S_cp_str_2
+
+D_to_S_cp_str_1:
+ lwz o0,0(a0)
+ addi a0,a0,4
+ stwu o0,4(a6)
+D_to_S_cp_str_2:
+ subic. d1,d1,1
+ bge D_to_S_cp_str_1
+
+ mr a0,d2
+ lwz r0,0(sp)
+ addi sp,sp,4
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ blr
+
+ csect .eqD
+eqD: lwz d0,0(a0)
+ lwz o0,0(a1)
+ cmpw 0,d0,o0
+ bne eqD_false
+
+ cmpw 0,d0,int_reg
+ beq eqD_INT
+
+ cmpw 0,d0,char_reg
+ beq eqD_CHAR
+
+ cmpw 0,d0,bool_reg
+ beq eqD_BOOL
+
+ cmpw 0,d0,real_reg
+ beq eqD_REAL
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+eqD_CHAR:
+eqD_INT: lwz d1,4(a0)
+ lwz o0,4(a1)
+ li d0,0
+ cmpw 0,d1,o0
+
+ mfcr d0
+ srwi d0,d0,31-2
+ andi. d0,d0,1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+eqD_BOOL: lbz d1,7(a0)
+ lbz o0,7(a1)
+ li d0,0
+ cmpw 0,d1,o0
+
+ mfcr d0
+ srwi d0,d0,31-2
+ andi. d0,d0,1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+eqD_REAL: lfd f0,4(a0)
+ lfd f1,4(a1)
+
+ fcmpo 0,f0,f1
+
+ mfcr d0
+ srwi d0,d0,31-2
+ andi. d0,d0,1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+eqD_false:
+ li d0,0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+;
+; the timer
+;
+
+_init_timer:
+ mflr r0
+ stwu r0,-4(sp)
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if LINUX
+ addi o0,sp,8
+ bl times
+ lwz o0,8(sp)
+ else
+ bl .TickCount
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lea o1,last_time
+ stw o0,0(o1)
+
+ lea o1,execute_time
+ li o0,0
+ stw o0,0(o1)
+
+ lea o1,garbage_collect_time
+ stw o0,0(o1)
+ if MEASURE_GC
+ lea o1,mark_compact_garbage_collect_time
+ stw o0,0(o1)
+
+ lea o1,compact_garbage_collect_time
+ stw o0,0(o1)
+ endif
+ lea o1,IO_time
+ stw o0,0(o1)
+
+ blr
+
+_get_time_diff:
+ mflr r0
+ stwu r0,-4(sp)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if LINUX
+ addi o0,sp,8
+ bl times
+ lwz o0,8(sp)
+ else
+ bl .TickCount
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ lea o2,last_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ stw o0,0(o2)
+ sub o0,o0,o1
+
+ blr
+
+.add_execute_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ bl _get_time_diff
+
+ lea o2,execute_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ add o1,o1,o0
+ stw o1,0(o2)
+
+ blr
+
+.add_garbage_collect_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ bl _get_time_diff
+
+ lea o2,garbage_collect_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ add o1,o1,o0
+ stw o1,0(o2)
+
+ blr
+
+.add_IO_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ bl _get_time_diff
+
+ lea o2,IO_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ add o1,o1,o0
+ stw o1,0(o2)
+
+ blr
+
+ if MEASURE_GC
+.add_mark_compact_garbage_collect_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ bl _get_time_diff
+
+ lea o2,mark_compact_garbage_collect_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ add o1,o1,o0
+ stw o1,0(o2)
+
+ blr
+
+.add_compact_garbage_collect_time:
+ mflr r0
+ stwu r0,-4(sp)
+
+ bl _get_time_diff
+
+ lea o2,compact_garbage_collect_time
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ lwz o1,0(o2)
+ add o1,o1,o0
+ stw o1,0(o2)
+
+ blr
+ endif
+;
+; the garbage collector
+;
+
+ csect .collect_3
+collect_3:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ stw a1,4(a4)
+ stw a2,8(a4)
+ addi a4,a4,12
+
+ mflr r0
+ bl collect_
+
+ lwz a2,-4(a4)
+ lwz a1,-8(a4)
+ lwzu a0,-12(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ mtlr r0
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_2
+collect_2:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ stw a1,4(a4)
+ addi a4,a4,8
+
+ mflr r0
+ bl collect_
+
+ lwz a1,-4(a4)
+ lwzu a0,-8(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ mtlr r0
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_1
+collect_1:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ addi a4,a4,4
+
+ mflr r0
+ bl collect_
+
+ lwzu a0,-4(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ mtlr r0
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_0
+collect_0:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ mflr r0
+ bl collect_
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ mtlr r0
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_03
+collect_03:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ stw a1,4(a4)
+ stw a2,8(a4)
+ addi a4,a4,12
+
+ mflr r0
+ bl collect_
+
+ lwz a2,-4(a4)
+ lwz a1,-8(a4)
+ lwzu a0,-12(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_02
+collect_02:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ stw a1,4(a4)
+ addi a4,a4,8
+
+ mflr r0
+ bl collect_
+
+ lwz a1,-4(a4)
+ lwzu a0,-8(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_01
+collect_01:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ stw a0,0(a4)
+ addi a4,a4,4
+
+ mflr r0
+ bl collect_
+
+ lwzu a0,-4(a4)
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+ csect .collect_00
+collect_00:
+ stwu r0,-4(sp)
+ if PROFILE
+ lea r3,garbage_collector_name
+ mflr r0
+ bl profile_s
+ endif
+ mflr r0
+ bl collect_
+
+ lwz r0,0(sp)
+ mtctr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ if PROFILE
+ b profile_ti
+ else
+ bctr
+ endif
+
+
+ csect ._collect_
+collect_:
+ stwu r0,-4(sp)
+
+ addi a6,a6,4
+ if USE_DCBZ
+ addi d7,d7,15
+ endif
+
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark3
+ endif
+
+ if MARK_GC
+ lea g1,bit_counter
+ lwz o2,0(g1)
+ li g0,0
+
+ tst o2
+ beq no_scan
+
+ mtctr o2
+
+ lea o4,heap_end_after_gc
+ lea a0,bit_vector_p
+ lwz o4,0(o4)
+ lwz a0,0(a0)
+ sub o4,o4,a6
+ srwi o4,o4,2
+ sub o4,o4,d7
+
+scan_bits:
+ lwz o0,0(a0)
+ addi a0,a0,4
+ cmpwi o0,0
+ beq zero_bits
+ stw g0,-4(a0)
+ bdnz scan_bits
+
+ b end_scan
+
+zero_bits:
+ mr a1,a0
+ bdnz skip_zero_bits_lp+4
+ b end_bits
+
+skip_zero_bits_lp:
+ bne end_zero_bits
+ lwz o3,0(a0)
+ addi a0,a0,4
+ tst o3
+ bdnz skip_zero_bits_lp
+
+ beq end_bits
+ stw g0,-4(a0)
+ sub o3,a0,a1
+ b end_bits2
+
+end_zero_bits:
+ lea g1,free_after_mark
+
+ sub o3,a0,a1
+ slwi o3,o3,3
+
+ cmplw 0,o3,o4
+
+ lwz o1,0(g1)
+ stw g0,-4(a0)
+
+ add o1,o1,o3
+ stw o1,0(g1)
+ blt scan_bits
+
+found_free_memory:
+ mfctr o2
+ lea o1,bit_counter
+ lea g1,bit_vector_p
+ stw o2,0(o1)
+ stw a0,0(g1)
+
+ lea o1,heap_vector
+ sub d7,o3,o4
+
+ lwz o1,0(o1)
+ subi o2,a1,4
+ lea g1,heap_p3
+ sub o2,o2,o1
+ lwz o1,0(g1)
+ slwi o2,o2,5
+
+ add a6,o2,o1
+
+ slwi o3,o3,2
+ lea g1,heap_end_after_gc
+ add o2,a6,o3
+ stw o2,0(g1)
+
+ if USE_DCBZ
+ subi d7,d7,15
+ li g2,32
+ endif
+ subi a6,a6,4
+ blr
+
+end_bits:
+ sub o3,a0,a1
+ addi o3,o3,4
+end_bits2:
+ lea g1,free_after_mark
+
+ slwi o3,o3,3
+
+ lwz o1,0(g1)
+ cmplw 0,o3,o4
+ add o1,o1,o3
+ stw o1,0(g1)
+ bge found_free_memory
+
+end_scan:
+ mfctr o2
+ lea g1,bit_counter
+ stw o2,0(g1)
+no_scan:
+ endif
+
+ if MARK_AND_COPY_GC
+no_mark3:
+ endif
+ mflr r0
+ stwu r0,-4(sp)
+
+ subi sp,sp,28
+ stw d0,0(sp)
+ stw d1,4(sp)
+ stw d2,8(sp)
+ stw d3,12(sp)
+ stw d4,16(sp)
+
+ lea g1,garbage_collect_flag
+
+ stw d5,20(sp)
+
+ lbz o0,0(g1)
+
+ stw d6,24(sp)
+
+ extsb o0,o0
+ cmpwi 0,o0,0
+ ble collect
+
+ subi o0,o0,2
+ stb o0,0(g1)
+
+ lea o0,heap_end_after_gc
+ lwz d0,0(o0)
+ sub d0,d0,a6
+ srwi d0,d0,2
+ lea o0,extra_heap_size
+ sub d0,d0,d7
+ lwz d1,0(o0)
+ cmplw 0,d0,d1
+ bgt collect
+
+ lea o0,extra_heap_size
+ lwz d1,0(o0)
+
+ lea o0,extra_heap
+
+ sub d7,d1,d0
+
+ lwz a6,0(o0)
+ slwi d1,d1,2
+ lea o0,heap_end_after_gc
+ add d1,d1,a6
+ stw d1,0(o0)
+
+ lwz d0,0(sp)
+ lwz d1,4(sp)
+ lwz d2,8(sp)
+ lwz d3,12(sp)
+ lwz d4,16(sp)
+ lwz d5,20(sp)
+ lwz d6,24(sp)
+
+ lwz r0,28(sp)
+ mtlr r0
+
+ if USE_DCBZ
+ subi d7,d7,15
+ li g2,32
+ endif
+ subi a6,a6,4
+
+ addi sp,sp,32
+ blr
+
+collect:
+ bl .add_execute_time
+
+ lea o1,flags
+ lwz o0,0(o1)
+ andi. r0,o0,4
+ beq no_print_stack_sizes
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ lea o0,garbage_collect_string_1
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+
+ lea o0,stack_p
+ lwz a0,0(o0)
+ sub o0,a4,a0
+ if MACOSX
+ lea o1,halt_sp
+ lwz d0,0(o1)
+ else
+ lea o1,stack_size
+ lwz o2,0(o1)
+ add d0,a0,o2
+ endif
+ sub d0,d0,sp
+ if STDERR_TO_FILE
+ bl .er_print_int
+ else
+ bl .ew_print_int
+ endif
+ nop
+
+ lea o0,garbage_collect_string_2
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+
+ mr o0,d0
+ if STDERR_TO_FILE
+ bl .er_print_int
+ else
+ bl .ew_print_int
+ endif
+ nop
+
+ lea o0,garbage_collect_string_3
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+no_print_stack_sizes:
+ cmplw 0,a4,sp
+ bgt stack_overflow
+
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ bne compacting_collector
+ else
+ if MARK_GC
+ b compacting_collector
+ endif
+ endif
+
+ if MARK_AND_COPY_GC || !MARK_GC
+ lea o0,garbage_collect_flag
+ lbz o1,0(o0)
+ extsb. o1,o1
+ bne compacting_collector
+
+ if COPIED_VECTOR
+ lea o1,heap_end_after_copy_gc
+ li g0,0
+ lwz a1,0(o1)
+ lea a2,heap_copied_vector
+ tst a1
+
+ lea o0,heap_copied_vector_size
+ lwz a2,0(a2)
+ lwz d1,0(o0)
+
+ beq zero_all
+
+ lea o0,heap_p1
+ stw g0,0(o1)
+ lwz a0,0(o0)
+ sub d0,a6,a0
+ addi d0,d0,63*4
+ srwi d0,d0,8
+ bl zero_bit_vector
+
+ sub d2,a1,a0
+ lea a2,heap_copied_vector
+ clrrwi d2,d2,8
+ lwz a2,0(a2)
+ srwi d2,d2,6
+ add a2,a2,d2
+
+ sub d0,d1,d2
+ srwi d0,d0,2
+ bl zero_bit_vector
+
+ b end_zero_bit_vector
+
+zero_all:
+ srwi d0,d1,2
+ bl zero_bit_vector
+
+end_zero_bit_vector:
+ endif
+
+; calculate alloc_size
+ lea o0,heap_end_after_gc
+ lwz d0,0(o0)
+ lea o1,alloc_size
+ sub d0,d0,a6
+ srwi d0,d0,2
+ sub d0,d0,d7
+ stw d0,0(o1)
+
+ include 'pcopy.a'
+
+ if WRITE_HEAP
+ lea o0,heap2_begin_and_end
+ stw o4,0(o0)
+ endif
+
+ lea o0,heap_end_after_gc
+ stw o4,0(o0)
+
+ sub d7,o4,a6
+ srwi d7,d7,2
+
+ bl .add_garbage_collect_time
+
+ lea o0,alloc_size
+ lwz o1,0(o0)
+ sub. d7,d7,o1
+ blt switch_to_mark_scan
+; bneg out_of_memory_4
+
+ slwi d0,d7,2
+ add d0,d0,d7
+ slwi d0,d0,5
+ lea o0,heap_size
+ lwz d2,0(o0)
+ slwi d1,d2,2
+ add d1,d1,d2
+ slwi d1,d1,1
+ add d1,d1,d2
+ cmplw 0,d0,d1
+ bge no_mark_scan
+; b no_mark_scan
+
+switch_to_mark_scan:
+ lea o0,heap_size_33
+ lwz d0,0(o0)
+ slwi d0,d0,5
+ lea o0,heap_p
+ lwz d1,0(o0)
+
+ lea o0,heap_p1
+ lwz d2,0(o0)
+ lea o0,heap_p2
+ lwz o1,0(o0)
+ cmplw 0,d2,o1
+ blt vector_at_begin
+
+vector_at_end:
+ lea o0,heap_p3
+ stw d1,0(o0)
+ add d1,d1,d0
+ lea o0,heap_vector
+ stw d1,0(o0)
+
+ lea o0,heap_p1
+ lwz d0,0(o0)
+ lea o0,extra_heap
+ stw d0,0(o0)
+ sub d1,d1,d0
+ srwi d1,d1,2
+ lea o0,extra_heap_size
+ stw d1,0(o0)
+ b switch_to_mark_scan_2
+
+vector_at_begin:
+ lea o0,heap_vector
+ stw d1,0(o0)
+ lea o1,heap_size
+ lwz o0,0(o1)
+ add d1,d1,o0
+ sub d1,d1,d0
+ lea o0,heap_p3
+ stw d1,0(o0)
+
+ lea o0,extra_heap
+ stw d1,0(o0)
+ lea o0,heap_p2
+ lwz d2,0(o0)
+ sub d2,d2,d1
+ srwi d2,d2,2
+ lea o0,extra_heap_size
+ stw d2,0(o0)
+
+switch_to_mark_scan_2:
+ lea o0,heap_size
+ lwz d0,0(o0)
+ srwi d0,d0,3
+ sub d0,d0,d7
+ slwi d0,d0,2
+
+ lea o0,garbage_collect_flag
+ li o1,1
+ stb o1,0(o0)
+
+ cmpwi 0,d7,0
+ bge end_garbage_collect
+
+ li o1,-1
+ stb o1,0(o0)
+
+ lea o0,extra_heap_size
+ lea o1,alloc_size
+ lwz d1,0(o0)
+ lwz d7,0(o1)
+ sub. d7,d1,d7
+ blt out_of_memory_4
+
+ lea o0,extra_heap
+ lea o1,heap_end_after_gc
+ if WRITE_HEAP
+ mr d2,a6
+ endif
+ lwz a6,0(o0)
+ slwi d1,d1,2
+ add d1,d1,a6
+ stw d1,0(o1)
+ if WRITE_HEAP
+ li d3,1
+ b end_garbage_collect_
+ else
+ b end_garbage_collect
+ endif
+
+no_mark_scan:
+; exchange the semi_spaces
+
+ lea o0,heap_p1
+ lea o1,heap_p2
+ lwz d0,0(o0)
+ lwz d1,0(o1)
+ stw d0,0(o1)
+ stw d1,0(o0)
+
+ if COPIED_VECTOR
+ lea o0,heap_size_129
+ lwz d1,0(o0)
+ slwi d1,d1,6-2
+ else
+ lea o0,heap_size
+ lwz d1,0(o0)
+ srwi d1,d1,3
+ endif
+ sub d0,d1,d7
+
+ if ADJUST_HEAP_SIZE
+ lea o0,heap_size_multiple
+ lwz o0,0(o0)
+
+ mullw d2,d0,o0
+ mulhwu o0,d0,o0
+
+ rlwinm d2,d2,32-9,9,31-2
+; srwi d2,d2,9
+
+ rlwimi d2,o0,32-9,0,8
+ srwi. o0,o0,9
+ bne no_small_heap1
+
+ cmplwi d2,MINIMUM_HEAP_SIZE/2
+ bge not_too_small1
+ li d2,MINIMUM_HEAP_SIZE/2
+not_too_small1:
+
+ sub. d2,d1,d2
+ blt no_small_heap1
+
+ sub d7,d7,d2
+ lea o0,heap_end_after_gc
+ slwi d2,d2,2
+ lwz d1,0(o0)
+ sub d2,d1,d2
+ lea o1,heap_end_after_copy_gc
+ stw d2,0(o0)
+ stw d1,0(o1)
+
+no_small_heap1:
+ endif
+
+ slwi d0,d0,2
+ endif
+
+end_garbage_collect:
+ if WRITE_HEAP
+ mr d2,a6
+ li d3,0
+end_garbage_collect_:
+ endif
+ lea o0,flags
+ lwz o1,0(o0)
+ andi. r0,o1,2
+ beq+ no_heap_use_message
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ lea o0,heap_use_after_gc_string_1
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ mr o0,d0
+ if STDERR_TO_FILE
+ bl .er_print_int
+ else
+ bl .ew_print_int
+ endif
+
+ lea o0,heap_use_after_gc_string_2
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+no_heap_use_message:
+ if FINALIZERS
+ bl call_finalizers
+ endif
+
+ if WRITE_HEAP
+ import first_function{DS}
+ import .write_heap
+ import min_write_heap_size
+
+ lea o0,flags
+ lea o1,min_write_heap_size
+
+ lwz o0,0(o0)
+ lwz o1,0(o1)
+
+ andi. r0,o0,32
+ beq no_write_heap
+
+ cmplw 0,d0,o1
+ blt no_write_heap
+
+ subi sp,sp,64
+
+ lea r3,garbage_collect_flag
+ cmpwi d3,0
+
+ lea r7,heap2_begin_and_end
+ lbz r3,0(r3)
+ lwz r5,0(r7)
+ bne copy_to_compact_with_alloc_in_extra_heap
+
+ extsb. r3,r3
+ lwz r6,4(r7)
+
+ lea r4,heap_p1
+ beq gc0
+ lea r4,heap_p2
+ bgt gc1
+ lea r4,heap_p3
+ li r5,0
+ li r6,0
+gc0:
+gc1:
+ lwz r4,0(r4)
+ mr r10,sp
+ stw r4,0(r10)
+ stw d2,4(r10)
+ stw r5,8(r10)
+ stw r6,12(r10)
+
+ lea r6,stack_p
+ lea r8,first_function
+ lwz r6,0(r6)
+ if LINUX
+ li r9,0
+ else
+ addi r9,rtoc,-32768
+ endif
+ lwz r8,0(r8)
+
+ stw r6,16(r10)
+ stw a4,20(r10)
+ stw r8,24(r10)
+ stw r9,28(r10)
+
+ lea r4,small_integers
+ lea r5,static_characters
+ stw r4,32(r10)
+ stw r5,36(r10)
+
+ stw r16,40(r10)
+ stw r15,44(r10)
+ stw r14,48(r10)
+ stw r13,52(r10)
+ lea d0,__STRING__2
+ lea d1,__ARRAY__2
+ stw d0,56(r10)
+ stw d1,60(r10)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+
+ mr r3,r10
+ bl .write_heap
+ nop
+
+ if MACOSX
+ lwz sp,0(sp)
+ addi sp,sp,64
+ else
+ addi sp,sp,128
+ endif
+no_write_heap:
+
+ endif
+
+ lwz d0,0(sp)
+ lwz d1,4(sp)
+ lwz d2,8(sp)
+ lwz d3,12(sp)
+ lwz d4,16(sp)
+ lwz d5,20(sp)
+ lwz d6,24(sp)
+
+ lwz r0,28(sp)
+ mtlr r0
+
+ if USE_DCBZ
+ subi d7,d7,15
+ li g2,32
+ endif
+ subi a6,a6,4
+
+ addi sp,sp,32
+ blr
+
+ if FINALIZERS
+call_finalizers:
+ lea d0,free_finalizer_list
+ lwz d0,0(d0)
+
+call_finalizers_lp:
+ lea o0,__Nil_m8
+ cmplw d0,o0
+ beq end_call_finalizers
+
+ lwz d1,8(d0)
+ lwz d0,4(d0)
+ mflr d2
+
+ lwz r12,0(d1)
+ lwz r3,4(d1)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+
+ lwz r0,0(r12)
+ stw RTOC,20(SP)
+ mtctr r0
+ lwz RTOC,4(r12)
+ bctrl
+ lwz RTOC,20(sp)
+
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+ mtlr d2
+ b call_finalizers_lp
+end_call_finalizers:
+ lea d0,free_finalizer_list
+ stw o0,0(d0)
+ blr
+ endif
+
+ if WRITE_HEAP
+copy_to_compact_with_alloc_in_extra_heap:
+ lwz r6,4(r7)
+ lea r4,heap_p2
+ b gc1
+ endif
+
+out_of_memory_4:
+ bl .add_garbage_collect_time
+
+ lea o0,out_of_memory_string_4
+ b print_error
+
+ csect .zero_bit_vector
+; d0 = n words
+; a2 = address
+; g0 = 0
+zero_bit_vector:
+ andi. r0,d0,1
+ srwi d0,d0,1
+ beq zero_bits1_1
+
+ stw g0,0(a2)
+ addi a2,a2,4
+zero_bits1_1:
+ andi. r0,d0,1
+ srwi d0,d0,1
+ beq zero_bits1_5
+
+ subi a2,a2,8
+ b zero_bits1_2
+
+zero_bits1_4:
+ stw g0,0(a2)
+ stw g0,4(a2)
+zero_bits1_2:
+ stw g0,8(a2)
+ stw g0,12(a2)
+ addi a2,a2,16
+zero_bits1_5:
+ subic. d0,d0,1
+ bge zero_bits1_4
+
+ blr
+
+ csect .reorder
+reorder:
+ mr d2,d0
+ mr d3,d1
+ slwi d4,d0,2
+ slwi d5,d1,2
+ add a0,a0,d5
+ sub a1,a1,d4
+ b st_reorder_lp
+
+reorder_lp:
+ lwzu o0,-4(a1)
+ subic. d2,d2,1
+
+ lwz o1,0(a0)
+ stw o0,0(a0)
+ addi a0,a0,4
+
+ bne+ next_b_in_element
+ mr d2,d0
+ add a0,a0,d5
+next_b_in_element:
+
+ subic. d3,d3,1
+ stw o1,0(a1)
+
+ bne+ next_a_in_element
+ mr d3,d1
+ sub a1,a1,d4
+next_a_in_element:
+
+st_reorder_lp:
+ cmplw 1,a1,a0
+ bgt 1,reorder_lp
+
+ blr
+
+;
+; the sliding compacting garbage collector
+;
+
+ csect text{PR}
+compacting_collector:
+
+; zero all mark bits
+
+ lea o0,heap_p3
+ lea o1,heap_vector
+ lwz d6,0(o0)
+ lea o0,heap_end_after_gc
+ lwz o4,0(o1)
+ lwz d5,0(o0)
+ sub d5,d5,a6
+ srwi d5,d5,2
+
+ lea o0,alloc_size
+ sub d5,d5,d7
+ stw d5,0(o0)
+
+ if MARK_GC
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark4
+ endif
+
+ lea o0,zero_bits_before_mark
+ li g0,0
+ lwz o1,0(o0)
+ cmpwi 0,o1,0
+ beq no_zero_bits
+
+ stw g0,0(o0)
+
+ if MARK_AND_COPY_GC
+no_mark4:
+ endif
+ endif
+
+ lea o0,heap_size_33
+ mr a2,o4
+ lwz d0,0(o0)
+ addi d0,d0,3
+ srwi d0,d0,2
+
+ li o0,0
+
+ andi. r0,d0,1
+ srwi d0,d0,1
+ beq zero_bits_1
+
+ stw o0,0(a2)
+ addi a2,a2,4
+zero_bits_1:
+
+ andi. r0,d0,1
+ srwi d0,d0,1
+ beq zero_bits_5
+
+ subi a2,a2,8
+ b zero_bits_2
+
+zero_bits_4:
+ stw o0,0(a2)
+ stw o0,4(a2)
+zero_bits_2:
+ stw o0,8(a2)
+ stw o0,12(a2)
+ addi a2,a2,16
+zero_bits_5:
+ subic. d0,d0,1
+ bge zero_bits_4
+
+ if MARK_GC
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark5
+ endif
+
+no_zero_bits:
+ lea o0,last_heap_free
+ lea o1,free_after_mark
+ lwz d0,0(o0)
+ lwz d1,0(o1)
+ slwi d1,d1,2
+
+ slwi d2,d1,3
+ add d2,d2,d1
+ srwi d2,d2,2
+
+ cmplw d0,d2
+ bgt compact_gc
+
+ if ADJUST_HEAP_SIZE
+ lea o0,bit_vector_size
+ lwz d1,0(o0)
+ lea o0,heap_size_multiple
+ slwi d1,d1,2
+ lwz o0,0(o0)
+ sub o2,d1,d0
+
+ mullw o1,o2,o0
+ mulhwu o2,o2,o0
+
+ rlwinm o1,o1,32-7,7,31-2
+; srwi o1,o1,7
+
+ rlwimi o1,o2,32-7,0,6
+ srwi. o2,o2,7
+ bne no_smaller_heap
+
+ cmplw o1,d1
+ bge no_smaller_heap
+
+ cmplwi d1,MINIMUM_HEAP_SIZE
+ ble no_smaller_heap
+
+ b compact_gc
+
+no_smaller_heap:
+ endif
+ include 'pmark.a'
+
+compact_gc:
+ lea o0,zero_bits_before_mark
+ li d0,1
+ stw d0,0(o0)
+ lea o0,last_heap_free
+ li g0,0
+ stw g0,0(o0)
+ lea o0,free_after_mark
+ li o1,1000
+ stw o1,0(o0)
+ endif
+
+ if MARK_AND_COPY_GC
+no_mark5:
+ endif
+
+
+ include 'pcompact.a'
+
+ lea o0,heap_size_33
+ lwz d7,0(o0)
+ lea o0,heap_end_after_gc
+ slwi d7,d7,5
+ add d7,d7,d6
+ stw d7,0(o0)
+
+ lea o0,alloc_size
+ sub d7,d7,a6
+ lwz d1,0(o0)
+ srwi d7,d7,2
+ sub. d7,d7,d1
+ blt out_of_memory_4
+
+ slwi d0,d7,2
+ lea o0,heap_size
+ add d0,d0,d7
+ lwz o1,0(o0)
+ slwi d0,d0,3
+ cmplw 0,d0,o1
+ blt out_of_memory_4
+
+ if MARK_GC || COMPACT_GC_ONLY
+ if MARK_GC && ADJUST_HEAP_SIZE
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ lwz o0,0(o0)
+ andi. r0,o0,64
+ beq no_mark6
+ endif
+
+ sub d0,a6,d6
+ lea o0,heap_size_multiple
+ slwi d1,d1,2
+ lwz o0,0(o0)
+ add o2,d0,d1
+
+ lea d1,heap_size_33
+ lwz d1,0(d1)
+ slwi d1,d1,5
+
+ mullw d0,o2,o0
+ mulhwu o0,o2,o0
+
+ rlwinm d0,d0,32-8,8,31-2
+; srwi d0,d0,8
+ rlwimi d0,o0,32-8,0,7
+; clrrwi d0,d0,2
+
+ srwi. o0,o0,8
+ bne no_small_heap2
+
+ cmplwi d0,MINIMUM_HEAP_SIZE
+ bge not_too_small2
+ li d0,MINIMUM_HEAP_SIZE
+not_too_small2:
+
+ sub. d2,d1,d0
+ blt no_small_heap2
+
+ lea o1,heap_end_after_gc
+ srwi o0,d2,2
+ lwz d1,0(o1)
+ sub d7,d7,o0
+ sub d1,d1,d2
+ stw d1,0(o1)
+
+ mr d1,d0
+
+no_small_heap2:
+ lea o0,bit_vector_size
+ srwi d1,d1,2
+ stw d1,0(o0)
+
+ if MARK_AND_COPY_GC
+no_mark6:
+ endif
+ endif
+ b no_copy_garbage_collection
+ else
+ lea o0,heap_size
+ slwi d0,d0,2
+ lwz d1,0(o0)
+ lwz o1,0(o0)
+ slwi d1,d1,5
+ sub d1,d1,o1
+ cmpw 0,d0,d1
+
+ ble no_copy_garbage_collection
+; b no_copy_garbage_collection
+
+ lea o0,heap_p
+ lwz d0,0(o0)
+ lea o0,heap_p1
+ stw d0,0(o0)
+ if COPIED_VECTOR
+ lea o0,heap_size_129
+ lwz d1,0(o0)
+ slwi d1,d1,6
+ add d0,d0,d1
+ lea o0,heap_copied_vector
+ lea o1,heap_end_after_gc
+ stw d0,0(o0)
+ lea o0,heap_copied_vector_size
+ stw d0,0(o1)
+ lwz d1,0(o0)
+ lea o0,heap_p2
+ add d1,d1,d0
+ stw d1,0(o0)
+ else
+ lea o0,heap_size
+ lwz d1,0(o0)
+ srwi d1,d1,1
+ add d0,d0,d1
+ lea o0,heap_p2
+ stw d0,0(o0)
+ lea o0,heap_end_after_gc
+ stw d0,0(o0)
+ endif
+ sub d0,d0,a6
+ srwi d0,d0,2
+ mr d7,d0
+ lea o0,alloc_size
+ lwz o1,0(o0)
+ sub d7,d7,o1
+
+ lea o0,heap_p3
+ lwz d0,0(o0)
+ lea o0,heap_vector
+ lwz o1,0(o0)
+ cmpw 0,d0,o1
+ ble vector_at_end_2
+
+ lea o0,heap_vector
+ lwz d1,0(o0)
+ lea o0,extra_heap
+ stw d1,0(o0)
+ sub d0,d0,d1
+ srwi d0,d0,2
+ lea o0,extra_heap_size
+ stw d0,0(o0)
+
+ lea o0,garbage_collect_flag
+ li o1,2
+ stb o1,0(o0)
+
+ b no_copy_garbage_collection
+
+vector_at_end_2:
+ lea o0,garbage_collect_flag
+ li o1,0
+ stb o1,0(o0)
+ endif
+
+no_copy_garbage_collection:
+ if MEASURE_GC
+ bl .add_compact_garbage_collect_time
+ else
+ bl .add_garbage_collect_time
+ endif
+ lea o0,alloc_size
+ sub d0,a6,d6
+ lwz d1,0(o0)
+ slwi d1,d1,2
+
+ add d0,d0,d1
+ b end_garbage_collect
+
+stack_overflow:
+ bl .add_execute_time
+
+ lea o0,stack_overflow_string
+ b print_error
+
+.IO_error:
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(128+28)(sp)
+ else
+ stwu sp,-128(sp)
+ endif
+ stw o0,124(sp)
+
+ lea o0,IO_error_string
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ lwz o0,124(sp)
+
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ lea o0,new_line_string
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,128
+ endif
+ b halt
+
+print_error:
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if STDERR_TO_FILE
+ bl .er_print_string
+ else
+ bl .ew_print_string
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+halt:
+
+ if PROFILE
+ mflr r0
+ stwu r0,-4(sp)
+ bl write_profile_stack
+ mtlr r0
+ endif
+
+ if EXCEPTIONS
+ lea o0,exception_info
+ lwz o0,0(o0)
+ cmpwi 0,o0,0
+ bne e__Exceptions__sraise__exception
+ endif
+
+ lea o0,halt_sp
+ lwz sp,0(o0)
+ if 0
+ lea o0,flags
+ lwz d0,0(o0)
+ andi. r0,d0,8
+ bne exit
+
+ andi. r0,d0,16
+ beq exit
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .wait_for_key_press
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ else
+ lea o0,execution_aborted
+ li d0,1
+ stw d0,0(o0)
+ endif
+ b exit
+
+ if EXCEPTIONS
+e__Exceptions__scatch__exception:
+ lea o0,exception_info
+ mflr d0
+ stw a4,0(o0)
+ stw sp,4(o0)
+ stw d0,8(o0)
+
+ li d0,0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+e__Exceptions__sraise__exception:
+ lea o0,exception_info
+ li d0,-1
+
+ lwz o1,8(o0)
+ lwz sp,4(o0)
+ mtlr o1
+ lwz a4,0(o0)
+
+ li o1,0
+ stw o1,0(o0)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+ endif
+
+ csect .eval_01
+eval_01:
+ stw a1,0(a4)
+ addi a4,a4,4
+ bctr
+
+ csect .eval_11
+eval_11:
+ stw a0,0(a4)
+ mr a0,a1
+ addi a4,a4,4
+ bctr
+
+ csect .eval_02
+eval_02:
+ stw a2,0(a4)
+ addi a4,a4,8
+ stw a1,4-8(a4)
+ bctr
+
+ csect .eval_12
+eval_12:
+ stw a0,4(a4)
+ mr a0,a1
+ stw a2,0(a4)
+ addi a4,a4,8
+ bctr
+
+ csect .eval_22
+eval_22:
+ stw a0,4(a4)
+ mr a0,a2
+ stw a1,0(a4)
+ addi a4,a4,8
+ bctr
+
+__eaind:
+eval_fill:
+ stw a0,0(a4)
+ mr a0,a1
+ lwz a1,0-NODE_POINTER_OFFSET(a1)
+ addi a4,a4,4
+
+ mtctr a1
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ mr a1,a0
+ lwzu a0,-4(a4)
+
+ lwz g0,0-NODE_POINTER_OFFSET(a1)
+ lwz g1,4-NODE_POINTER_OFFSET(a1)
+ stw g0,0-NODE_POINTER_OFFSET(a0)
+ lwz g0,8-NODE_POINTER_OFFSET(a1)
+ stw g1,4-NODE_POINTER_OFFSET(a0)
+ stw g0,8-NODE_POINTER_OFFSET(a0)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ b eval_fill
+ nop
+ nop
+ if LINUX
+ nop
+ nop
+ endif
+ dc.l 0
+ dc.l -2
+__indirection:
+ lwz a1,4(a0)
+ lwz d0,0(a1)
+ andi. r0,d0,2
+ if MARK_GC
+ beq eval_fill2
+ else
+ beq _cycle__in__spine
+ endif
+ stw d0,0(a0)
+ lwz g0,4(a1)
+ lwz g1,8(a1)
+ stw g0,4(a0)
+ stw g1,8(a0)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+_cycle__in__spine:
+ b __cycle__in__spine
+
+ if MARK_GC
+ csect .eval_fill2
+eval_fill2:
+ if MARK_AND_COPY_GC
+ lea o0,flags
+ stw a5,0-NODE_POINTER_OFFSET(a0)
+ lwz o0,0(o0)
+ stw a0,0(a4)
+ andi. r0,o0,64
+ beq _cycle__in__spine
+ else
+ stw a5,0-NODE_POINTER_OFFSET(a0)
+ stw a0,0(a4)
+ endif
+ addi a4,a4,4
+ mr a0,a1
+
+ mtctr d0
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ lwzu a1,-4(a4)
+ lwz o0,0-NODE_POINTER_OFFSET(a0)
+ lwz o1,4-NODE_POINTER_OFFSET(a0)
+ stw o0,0-NODE_POINTER_OFFSET(a1)
+ lwz o0,8-NODE_POINTER_OFFSET(a0)
+ stw o1,4-NODE_POINTER_OFFSET(a1)
+ stw o0,8-NODE_POINTER_OFFSET(a1)
+ mr a0,a1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+ endif
+
+ csect .eval_upd_0
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_0:
+ lea a3,__indirection
+ mtctr a2
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ stw a3,0-NODE_POINTER_OFFSET(a1)
+ bctr
+
+ csect .eval_upd_1
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_1:
+ lea a3,__indirection
+ mtctr a2
+ lwz d0,4-NODE_POINTER_OFFSET(a1)
+ stw a3,0-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ mr a1,d0
+ bctr
+
+ csect .eval_upd_2
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_2:
+ mtctr a2
+ lea a2,__indirection
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ lwz a1,8-NODE_POINTER_OFFSET(a1)
+ bctr
+
+ csect .eval_upd_3
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_3:
+ mtctr a2
+ lea a2,__indirection
+ stw a0,0(a4)
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ addi a4,a4,4
+ lwz a0,12-NODE_POINTER_OFFSET(a1)
+ lwz a1,8-NODE_POINTER_OFFSET(a1)
+ bctr
+
+ csect .eval_upd_4
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_4:
+ mtctr a2
+ lea a2,__indirection
+ stw a0,0(a4)
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ lwz g1,16-NODE_POINTER_OFFSET(a1)
+ lwz a0,12-NODE_POINTER_OFFSET(a1)
+ stw g1,4(a4)
+ addi a4,a4,8
+ lwz a1,8-NODE_POINTER_OFFSET(a1)
+ bctr
+
+ csect .eval_upd_5
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_5:
+ mtctr a2
+ lea a2,__indirection
+ stw a0,0(a4)
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ lwz g1,20-NODE_POINTER_OFFSET(a1)
+ lwz a0,12-NODE_POINTER_OFFSET(a1)
+ stw g1,4(a4)
+ lwz g1,16-NODE_POINTER_OFFSET(a1)
+ lwz a1,8-NODE_POINTER_OFFSET(a1)
+ stw g1,8(a4)
+ addi a4,a4,12
+ bctr
+
+ csect .eval_upd_6
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_6:
+ mtctr a2
+ lea a2,__indirection
+ stw a0,0(a4)
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ lwz g1,24-NODE_POINTER_OFFSET(a1)
+ lwz a0,12-NODE_POINTER_OFFSET(a1)
+ stw g1,4(a4)
+ lwz g1,20-NODE_POINTER_OFFSET(a1)
+ stw g1,8(a4)
+ lwz g1,16-NODE_POINTER_OFFSET(a1)
+ lwz a1,8-NODE_POINTER_OFFSET(a1)
+ stw g1,12(a4)
+ addi a4,a4,16
+ bctr
+
+ csect .eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_7:
+ li d0,0
+ li d1,20
+eval_upd_n:
+ mtctr a2
+ lea a2,__indirection
+ stw a0,0(a4)
+ stw a2,0-NODE_POINTER_OFFSET(a1)
+ lwz a2,4-NODE_POINTER_OFFSET(a1)
+ stw a0,4-NODE_POINTER_OFFSET(a1)
+ add a1,a1,d1
+ lwz g1,8-NODE_POINTER_OFFSET(a1)
+ stw g1,4(a4)
+ lwz g1,4-NODE_POINTER_OFFSET(a1)
+ stw g1,8(a4)
+ lwz g1,0-NODE_POINTER_OFFSET(a1)
+ stw g1,12(a4)
+ addi a4,a4,16
+eval_upd_n_lp:
+ lwz g1,-4-NODE_POINTER_OFFSET(a1)
+ subi a1,a1,4
+ stw g1,0(a4)
+ subic. d0,d0,1
+ addi a4,a4,4
+ bge eval_upd_n_lp
+
+ lwz a0,-4-NODE_POINTER_OFFSET(a1)
+ lwz a1,-8-NODE_POINTER_OFFSET(a1)
+ bctr
+
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_8:
+ li d0,1
+ li d1,24
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_9:
+ li d0,2
+ li d1,28
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_10:
+ li d0,3
+ li d1,32
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_11:
+ li d0,4
+ li d1,36
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_12:
+ li d0,5
+ li d1,40
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_13:
+ li d0,6
+ li d1,44
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_14:
+ li d0,7
+ li d1,48
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_15:
+ li d0,8
+ li d1,52
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_16:
+ li d0,9
+ li d1,56
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_17:
+ li d0,10
+ li d1,60
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_18:
+ li d0,11
+ li d1,64
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_19:
+ li d0,12
+ li d1,68
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_20:
+ li d0,13
+ li d1,72
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_21:
+ li d0,14
+ li d1,76
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_22:
+ li d0,15
+ li d1,80
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_23:
+ li d0,16
+ li d1,84
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_24:
+ li d0,17
+ li d1,88
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_25:
+ li d0,18
+ li d1,92
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_26:
+ li d0,19
+ li d1,96
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_27:
+ li d0,20
+ li d1,100
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_28:
+ li d0,21
+ li d1,104
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_29:
+ li d0,22
+ li d1,108
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_30:
+ li d0,23
+ li d1,112
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_31:
+ li d0,24
+ li d1,116
+ b eval_upd_n
+ if PROFILE
+ mflr r0
+ bl profile_n
+ endif
+eval_upd_32:
+ li d0,25
+ li d1,120
+ b eval_upd_n
+
+;
+; STRINGS
+;
+ csect .catAC
+catAC:
+ if NODE_POINTER_OFFSET==0
+ lwzu d0,4(a0)
+ lwzu d1,4(a1)
+ else
+ lwz d0,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,4
+ lwz d1,4-NODE_POINTER_OFFSET(a1)
+ baddi a1,4
+ endif
+ add d2,d0,d1
+ addi d5,d2,3+8
+ srwi d5,d5,2
+ sub. d7,d7,d5
+; reserve one word extra, because
+; word after the string may change
+ addi d6,d2,3
+ ble gc_3
+gc_r_3:
+
+ lea o1,__STRING__2
+ addi d3,a6,4+NODE_POINTER_OFFSET
+ stw o1,4(a6)
+ stwu d2,8(a6)
+
+; copy string 1
+
+ addi d2,d1,3
+ srwi d2,d2,2
+ mr a2,a6
+
+ subic. d2,d2,1
+ blt cat_string_4
+cat_string_3:
+ if NODE_POINTER_OFFSET==0
+ lwzu o0,4(a1)
+ else
+ lwz o0,4-NODE_POINTER_OFFSET(a1)
+ baddi a1,4
+ endif
+ subic. d2,d2,1
+ stwu o0,4(a2)
+ bge cat_string_3
+cat_string_4:
+
+; copy string 2
+
+ addi d0,d0,3
+ srwi d0,d0,2
+ subic. d0,d0,1
+ add a2,a6,d1
+ blt cat_string_1
+
+cat_string_0:
+ if NODE_POINTER_OFFSET==0
+ lwzu o0,4(a0)
+ else
+ lwz o0,4-NODE_POINTER_OFFSET(a0)
+ baddi a0,4
+ endif
+ subic. d0,d0,1
+ stwu o0,4(a2)
+ bge cat_string_0
+cat_string_1:
+
+ clrrwi d6,d6,2
+ mr a0,d3
+ add a6,a6,d6
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_3: subi d7,d7,1
+ subi a0,a0,4
+ subi a1,a1,4
+ mflr r0
+ bl collect_2
+ addi a0,a0,4
+ addi a1,a1,4
+ addi d7,d7,1
+ b gc_r_3
+
+ csect .sliceAC
+empty_string:
+ lea a0,zero_length_string
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+sliceAC:
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ addi a2,a0,4-NODE_POINTER_OFFSET
+ cmpwi 0,d1,0
+ bge slice_string_1
+
+ li d1,0
+
+slice_string_1:
+ cmpw 0,d1,d2
+ bge empty_string
+ cmpw 0,d0,d1
+ addi d0,d0,1
+ blt empty_string
+
+ cmpw 0,d0,d2
+ ble slice_string_2
+
+ mr d0,d2
+
+slice_string_2:
+ sub d0,d0,d1
+
+ subi d7,d7,2
+
+ addi d2,d0,3
+ srwi d2,d2,2
+
+ sub. d7,d7,d2
+ blt gc_4
+r_gc_4:
+ lea o1,__STRING__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o1,4(a6)
+ stwu d0,8(a6)
+
+ add a2,a2,d1
+ subic. d2,d2,1
+ blt slice_string__1
+
+slice_string__0:
+ lwzu o0,4(a2)
+ subic. d2,d2,1
+ stwu o0,4(a6)
+ bge slice_string__0
+slice_string__1:
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_4: mflr r0
+ bl collect_1
+ addi a2,a0,4-NODE_POINTER_OFFSET
+ b r_gc_4
+
+ csect .updateAC
+updateAC:
+ lwz d2,4-NODE_POINTER_OFFSET(a0)
+ addi a2,a0,4-NODE_POINTER_OFFSET
+ cmplw 0,d1,d2
+ bge update_string_error
+
+ addi d3,d2,3
+ subi d7,d7,2
+
+ srwi d3,d3,2
+ sub. d7,d7,d3
+ blt gc_5
+r_gc_5:
+ lea o1,__STRING__2
+
+ subic. d3,d3,1
+
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o1,4(a6)
+ stwu d2,8(a6)
+ blt update_string_5
+
+update_string_4:
+ lwzu o0,4(a2)
+ subic. d3,d3,1
+ stwu o0,4(a6)
+ bge update_string_4
+update_string_5:
+
+ addi d1,d1,8
+ lwz r0,0(sp)
+ stbx d0,a0,d1
+ addi sp,sp,4
+ blr
+
+gc_5: mflr r0
+ bl collect_1
+ addi a2,a0,4-NODE_POINTER_OFFSET
+ b r_gc_5
+
+
+update_string_error:
+ lea o0,high_index_string
+ cmpwi 0,d1,0
+ bge print_error
+
+ lea o0,low_index_string
+update_string_error_2:
+ b print_error
+
+ csect .eqAC
+eqAC:
+ lwzu d0,4-NODE_POINTER_OFFSET(a0)
+ lwzu o0,4-NODE_POINTER_OFFSET(a1)
+ cmpw 0,d0,o0
+ bne equal_string_ne
+
+ andi. d1,d0,3
+ srwi d0,d0,2
+ subic. d0,d0,1
+ blt equal_string_b
+
+equal_string_1:
+ lwzu o0,4(a1)
+ lwzu o1,4(a0)
+
+ cmpw o1,o0
+ bne equal_string_ne
+
+ subic. d0,d0,1
+ bge equal_string_1
+
+equal_string_b:
+ subic. d1,d1,1
+ blt equal_string_eq
+
+equal_string_2:
+ lbz o0,4(a1)
+ addi a1,a1,1
+ lbz o1,4(a0)
+ addi a0,a0,1
+ cmpw o1,o0
+ bne equal_string_ne
+
+ subic. d1,d1,1
+ bge equal_string_2
+
+equal_string_eq:
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+equal_string_ne:
+ li d0,0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .cmpAC
+cmpAC:
+ lwzu d1,4-NODE_POINTER_OFFSET(a0)
+ lwzu d2,4-NODE_POINTER_OFFSET(a1)
+
+ cmplw 0,d2,d1
+ blt cmp_string_less
+
+ li d0,0
+ beq cmp_string_chars
+
+ li d0,1
+ b cmp_string_chars
+
+cmp_string_less:
+ li d0,-1
+ mr d1,d2
+cmp_string_chars:
+ andi. d2,d1,3
+ srwi d1,d1,2
+ subic. d1,d1,1
+ blt cmp_string_b
+
+cmp_string_1:
+ lwzu o0,4(a0)
+ lwzu o1,4(a1)
+
+ cmplw 0,o1,o0
+ bne cmp_string_ne
+
+ subic. d1,d1,1
+ bge cmp_string_1
+
+cmp_string_b:
+ subic. d2,d2,1
+ blt cmp_string_eq
+
+cmp_string_2:
+ lbz o0,4(a0)
+ lbz o1,4(a1)
+ addi a0,a0,1
+
+ cmplw 0,o1,o0
+ addi a1,a1,1
+ bne cmp_string_ne
+
+ subic. d2,d2,1
+ bge cmp_string_2
+
+cmp_string_eq:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+cmp_string_ne:
+ bgt cmp_string_r1
+
+ li d0,-1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+cmp_string_r1:
+ li d0,1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .string_to_string_node
+string_to_string_node:
+ lwz d0,0(a0)
+ addi a0,a0,4
+
+ addi d1,d0,3
+ srwi d1,d1,2
+
+ subi d7,d7,2
+ sub. d7,d7,d1
+ blt string_to_string_node_gc
+
+string_to_string_node_r:
+ lea o0,__STRING__2
+ stw o0,4(a6)
+ addi d2,a6,4+NODE_POINTER_OFFSET
+ stwu d0,8(a6)
+ b string_to_string_node_4
+
+string_to_string_node_2:
+ lwz o0,0(a0)
+ addi a0,a0,4
+ stwu o0,4(a6)
+string_to_string_node_4:
+ subic. d1,d1,1
+ bge string_to_string_node_2
+
+ mr a0,d2
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+string_to_string_node_gc:
+ mflr r0
+ stwu a0,-4(sp)
+ bl collect_0
+
+ lwz a0,0(sp)
+ addi sp,sp,4
+ b string_to_string_node_r
+
+ csect _cn
+ dc.l 3
+_c3: b __cycle__in__spine
+ dc.l 4
+_c4: b __cycle__in__spine
+ dc.l 5
+_c5: b __cycle__in__spine
+ dc.l 6
+_c6: b __cycle__in__spine
+ dc.l 7
+_c7: b __cycle__in__spine
+ dc.l 8
+_c8: b __cycle__in__spine
+ dc.l 9
+_c9: b __cycle__in__spine
+ dc.l 10
+_c10: b __cycle__in__spine
+ dc.l 11
+_c11: b __cycle__in__spine
+ dc.l 12
+_c12: b __cycle__in__spine
+ dc.l 13
+_c13: b __cycle__in__spine
+ dc.l 14
+_c14: b __cycle__in__spine
+ dc.l 15
+_c15: b __cycle__in__spine
+ dc.l 16
+_c16: b __cycle__in__spine
+ dc.l 17
+_c17: b __cycle__in__spine
+ dc.l 18
+_c18: b __cycle__in__spine
+ dc.l 19
+_c19: b __cycle__in__spine
+ dc.l 20
+_c20: b __cycle__in__spine
+ dc.l 21
+_c21: b __cycle__in__spine
+ dc.l 22
+_c22: b __cycle__in__spine
+ dc.l 23
+_c23: b __cycle__in__spine
+ dc.l 24
+_c24: b __cycle__in__spine
+ dc.l 25
+_c25: b __cycle__in__spine
+ dc.l 26
+_c26: b __cycle__in__spine
+ dc.l 27
+_c27: b __cycle__in__spine
+ dc.l 28
+_c28: b __cycle__in__spine
+ dc.l 29
+_c29: b __cycle__in__spine
+ dc.l 30
+_c30: b __cycle__in__spine
+ dc.l 31
+_c31: b __cycle__in__spine
+ dc.l 32
+_c32: b __cycle__in__spine
+
+;
+; ARRAYS
+;
+
+ csect .create_arrayB
+create_arrayB:
+ mr d2,d1
+ addi d1,d1,3
+ srwi d1,d1,2
+ subi d7,d7,3
+ sub. d7,d7,d1
+ bge+ no_collect_4575
+
+ mflr r0
+ bl collect_0
+
+no_collect_4575:
+ slwi d3,d0,8
+ or d0,d0,d3
+ slwi d3,d0,16
+ or d0,d0,d3
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d2,8(a6)
+ stwu bool_reg,12(a6)
+ b create_arrayBCI
+
+ csect .create_arrayC
+create_arrayC:
+ mr d2,d1
+ addi d1,d1,3
+ srwi d1,d1,2
+ subi d7,d7,2
+ sub. d7,d7,d1
+ bge+ no_collect_4578
+
+ mflr r0
+ bl collect_0
+
+no_collect_4578:
+ slwi d3,d0,8
+ or d0,d0,d3
+ slwi d3,d0,16
+ or d0,d0,d3
+ lea o0,__STRING__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stwu d2,8(a6)
+ b create_arrayBCI
+
+ csect .create_arrayI
+create_arrayI:
+ subi d7,d7,3
+ sub. d7,d7,d1
+ bge+ no_collect_4577
+
+ mflr r0
+ bl collect_0
+
+no_collect_4577:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d1,8(a6)
+ stwu int_reg,12(a6)
+
+create_arrayBCI:
+ andi. o0,d1,1
+ beq st_filli_array
+
+ stwu d0,4(a6)
+
+st_filli_array:
+ srwi. d1,d1,1
+ beq skip_filli_array
+
+ mtctr d1
+filli_array:
+ stw d0,4(a6)
+ stwu d0,8(a6)
+ bdnz filli_array
+
+skip_filli_array:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .create_arrayR
+create_arrayR:
+ stfd f14,-8(sp)
+ sub d7,d7,d0
+
+ lwz d1,-8(sp)
+ subi d7,d7,3+1
+
+ lwz d2,-4(sp)
+ sub. d7,d7,d0
+ bge+ no_collect_4579
+
+ mflr r0
+ bl collect_0
+
+no_collect_4579:
+ addi a6,a6,4
+
+ rlwinm d3,a6,32-2,31,31
+ lea o0,__ARRAY__2
+
+ rlwinm a6,a6,0,0,31-3
+ add d7,d7,d3
+
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+
+ cmpwi 0,d0,0
+
+ stw d0,8(a6)
+ stwu real_reg,12(a6)
+ beq skip_fillr_array
+
+ mtctr d0
+fillr_array:
+ stw d1,4(a6)
+ stwu d2,8(a6)
+ bdnz fillr_array
+
+skip_fillr_array:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .create_array
+create_array:
+ subi d7,d7,3
+ sub. d7,d7,d0
+ bge+ no_collect_4576
+
+ mflr r0
+ bl collect_1
+
+no_collect_4576:
+ mr d1,a0
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ li g0,0
+ stwu g0,12(a6)
+ lwz r0,0(sp)
+ addi sp,sp,4
+ b fillr1_array
+
+create_R_array:
+ subic. d2,d2,2
+ blt create_R_array_1
+ beq create_R_array_2
+ subic. d2,d2,2
+ blt create_R_array_3
+ beq create_R_array_4
+ b create_R_array_5
+
+create_R_array_1:
+ subi d7,d7,3
+ sub. d7,d7,d0
+ bge+ no_collect_4581
+
+ mflr r0
+ bl collect_0
+
+no_collect_4581:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+ cmpwi 0,d3,0
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ beq r_array_1_b
+
+ lwz d1,-4(a4)
+ b fillr1_array
+
+r_array_1_b:
+ lwz d1,0(sp)
+
+fillr1_array:
+ andi. o0,d0,1
+ beq st_fillr1_array_1
+
+ stwu d1,4(a6)
+st_fillr1_array_1:
+ srwi. d0,d0,1
+ beq skip_fillr1_array_lp
+
+ mtctr d0
+fillr1_array_lp:
+ stw d1,4(a6)
+ stwu d1,8(a6)
+ bdnz fillr1_array_lp
+
+skip_fillr1_array_lp:
+ blr
+
+create_R_array_2:
+ subi d7,d7,3
+ sub d7,d7,d0
+ sub. d7,d7,d0
+ bge+ no_collect_4582
+
+ mflr r0
+ bl collect_0
+
+no_collect_4582:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+
+ subic. d3,d3,1
+ blt r_array_2_bb
+ beq r_array_2_ab
+r_array_2_aa:
+ lwz d1,-4(a4)
+ lwz d2,-8(a4)
+ b st_fillr2_array
+r_array_2_ab:
+ lwz d1,-4(a4)
+ lwz d2,0(sp)
+ b st_fillr2_array
+r_array_2_bb:
+ lwz d1,0(sp)
+ lwz d2,4(sp)
+ b st_fillr2_array
+
+st_fillr2_array:
+ cmpwi 0,d0,0
+ beq skip_fillr2_array_1
+
+ mtctr d0
+fillr2_array_1:
+ stw d1,4(a6)
+ stwu d2,8(a6)
+ bdnz fillr2_array_1
+
+skip_fillr2_array_1:
+ blr
+
+create_R_array_3:
+ subi d7,d7,3
+ sub d7,d7,d0
+ sub d7,d7,d0
+ sub. d7,d7,d0
+ bge+ no_collect_4583
+
+ mflr r0
+ bl collect_0
+
+no_collect_4583:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+
+ cmpwi 0,d3,0
+
+ lwz r0,0(sp)
+ addi a2,sp,4
+ addi sp,sp,4
+
+ beq r_array_3
+
+ slwi d4,d3,2
+ sub a3,a4,d4
+ subi d3,d3,1
+
+copy_a_to_b_lp3:
+ subic. d3,d3,1
+
+ lwz o0,0(a3)
+ addi a3,a3,4
+ stwu o0,-4(sp)
+ bge copy_a_to_b_lp3
+
+r_array_3:
+ lwz d1,0(sp)
+ cmpwi 0,d0,0
+
+ lwz d2,4(sp)
+ lwz d3,8(sp)
+ mr sp,a2
+
+ beq skip_fillr3_array
+
+ mtctr d0
+fillr3_array_1:
+ stw d1,4(a6)
+ stw d2,8(a6)
+ stwu d3,12(a6)
+ bdnz fillr3_array_1
+
+skip_fillr3_array:
+ blr
+
+create_R_array_4:
+ subi d7,d7,3
+ slwi d2,d0,2
+ sub. d7,d7,d2
+ bge+ no_collect_4584
+
+ mflr r0
+ bl collect_0
+
+no_collect_4584:
+ lea o1,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o1,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+
+ cmpwi 0,d3,0
+
+ lwz r0,0(sp)
+ addi a2,sp,4
+ addi sp,sp,4
+
+ beq r_array_4
+
+ slwi d4,d3,2
+ sub a3,a4,d4
+ subi d3,d3,1
+
+copy_a_to_b_lp4:
+ subic. d3,d3,1
+ lwz o1,0(a3)
+ addi a3,a3,4
+ stwu o1,-4(sp)
+ bge copy_a_to_b_lp4
+
+r_array_4:
+ lwz d1,0(sp)
+ lwz d2,4(sp)
+ cmpwi 0,d0,0
+
+ lwz d3,8(sp)
+ lwz d4,12(sp)
+ mr sp,a2
+ beq skip_fillr4_array
+
+ mtctr d0
+fillr4_array:
+ stw d1,4(a6)
+ stw d2,8(a6)
+ stw d3,12(a6)
+ stwu d4,16(a6)
+ bdnz fillr4_array
+
+skip_fillr4_array:
+ blr
+
+create_R_array_5:
+ subi d7,d7,3
+ slwi d4,d0,2
+ sub d7,d7,d4
+ mr d5,d2
+sub_size_lp:
+ subic. d5,d5,1
+ sub d7,d7,d0
+ bgt sub_size_lp
+
+ tst d7
+ bge+ no_collect_4585
+
+ mflr r0
+ bl collect_0
+
+no_collect_4585:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+
+ cmpwi 0,d3,0
+
+ lwz r0,0(sp)
+ addi a2,sp,4
+ addi sp,sp,4
+ mr d5,d2
+
+ beq r_array_5
+
+ slwi d4,d3,2
+ sub a3,a4,d4
+ subi d3,d3,1
+
+copy_a_to_b_lp5:
+ subic. d3,d3,1
+
+ lwz o0,0(a3)
+ addi a3,a3,4
+ stwu o0,-4(sp)
+ bge copy_a_to_b_lp5
+
+r_array_5:
+ lwz d1,0(sp)
+ lwz d2,4(sp)
+ lwz d3,8(sp)
+ lwz d4,12(sp)
+ b st_fillr5_array
+
+fillr5_array_1:
+ stw d1,4(a6)
+ stw d2,8(a6)
+ mtctr d5
+ stw d3,12(a6)
+ addi a3,sp,16
+ stwu d4,16(a6)
+
+copy_elem_lp5:
+ lwz o0,0(a3)
+ addi a3,a3,4
+ stwu o0,4(a6)
+ bdnz copy_elem_lp5
+
+st_fillr5_array:
+ subic. d0,d0,1
+ bge fillr5_array_1
+
+ mr sp,a2
+ blr
+
+ csect .e__system__sAP
+e__system__sAP:
+ lwz a2,0(a1)
+ lwz a2,4-2(a2)
+ mtctr a2
+ bctr
+
+; _ARRAYS
+
+ csect ._create_arrayB
+_create_arrayB:
+ mr d1,d0
+ addi d0,d0,3
+ srwi d0,d0,2
+ subi d7,d7,3
+ sub. d7,d7,d0
+ bge+ no_collect_3575
+
+ mflr r0
+ bl collect_0
+
+no_collect_3575:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d1,8(a6)
+ stwu bool_reg,12(a6)
+ slwi d0,d0,2
+ add a6,a6,d0
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect ._create_arrayC
+_create_arrayC:
+ mr d1,d0
+ addi d0,d0,3
+ srwi d0,d0,2
+ subi d7,d7,2
+ sub. d7,d7,d0
+ bge+ no_collect_3578
+
+ mflr r0
+ bl collect_0
+
+no_collect_3578:
+ lea o0,__STRING__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stwu d1,8(a6)
+ slwi d0,d0,2
+ add a6,a6,d0
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect ._create_arrayI
+_create_arrayI:
+ subi d7,d7,3
+ sub. d7,d7,d0
+ bge+ no_collect_3577
+
+ mflr r0
+ bl collect_0
+
+no_collect_3577:
+ lea o0,__ARRAY__2
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu int_reg,12(a6)
+ slwi d0,d0,2
+ add a6,a6,d0
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect ._create_arrayR
+_create_arrayR:
+ sub d7,d7,d0
+ subi d7,d7,3+1
+ sub. d7,d7,d0
+ bge+ no_collect_3579
+
+ mflr r0
+ bl collect_0
+
+no_collect_3579:
+ addi a6,a6,4
+
+ lea o0,__ARRAY__2
+ rlwinm d3,a6,32-2,31,31
+
+ rlwinm a6,a6,0,0,31-3
+ add d7,d7,d3
+
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ slwi d0,d0,3
+ stwu real_reg,12(a6)
+ add a6,a6,d0
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+; d0: number of elements, d1: element descriptor, d2: element size,
+; d3: element a size a0: a_element -> a0: array
+
+ csect ._create_r_array
+_create_r_array:
+ subi d7,d7,3
+ mr d5,d2
+sub_size_lp2:
+ subic. d5,d5,1
+ sub d7,d7,d0
+ bgt sub_size_lp2
+
+ tst d7
+ bge+ no_collect_3585
+
+ mflr r0
+ bl collect_1
+
+no_collect_3585:
+ lea o0,__ARRAY__2
+ mr d4,a0
+ addi a0,a6,4+NODE_POINTER_OFFSET
+ stw o0,4(a6)
+ stw d0,8(a6)
+ stwu d1,12(a6)
+
+ tst d3
+ lwz r0,0(sp)
+ addi sp,sp,4
+ beq _create_r_array_0
+ subic. d3,d3,2
+ blt _create_r_array_1
+ beq _create_r_array_2
+ subic. d3,d3,2
+ blt _create_r_array_3
+ beq _create_r_array_4
+ b _create_r_array_5
+
+_create_r_array_0:
+ tst d2
+ mtctr d2
+ slwi d0,d0,2
+ beq _skip_fillr0_array_lp
+_fillr0_array_1:
+ add a6,a6,d0
+ bdnz _fillr0_array_1
+_skip_fillr0_array_lp:
+ blr
+
+_create_r_array_1:
+ tst d0
+ mtctr d0
+ slwi d2,d2,2
+ beq _skip_fillr1_array_lp
+_fillr1_array_lp:
+ stw d4,4(a6)
+ add a6,a6,d2
+ bdnz _fillr1_array_lp
+_skip_fillr1_array_lp:
+ blr
+
+_create_r_array_2:
+ tst d0
+ mtctr d0
+ slwi d2,d2,2
+ beq _skip_fillr2_array_1
+_fillr2_array_1:
+ stw d4,4(a6)
+ stw d4,8(a6)
+ add a6,a6,d2
+ bdnz _fillr2_array_1
+_skip_fillr2_array_1:
+ blr
+
+_create_r_array_3:
+ tst d0
+ mtctr d0
+ slwi d2,d2,2
+ beq _skip_fillr3_array
+_fillr3_array_1:
+ stw d4,4(a6)
+ stw d4,8(a6)
+ stw d4,12(a6)
+ add a6,a6,d2
+ bdnz _fillr3_array_1
+_skip_fillr3_array:
+ blr
+
+_create_r_array_4:
+ tst d0
+ mtctr d0
+ slwi d2,d2,2
+ beq _skip_fillr4_array
+_fillr4_array:
+ stw d4,4(a6)
+ stw d4,8(a6)
+ stw d4,12(a6)
+ stw d4,16(a6)
+ add a6,a6,d2
+ bdnz _fillr4_array
+_skip_fillr4_array:
+ blr
+
+_create_r_array_5:
+ mr d1,d3
+ subi d2,d2,4
+ sub d2,d2,d3
+ slwi d2,d2,2
+ b _st_fillr5_array
+
+_fillr5_array_1:
+ stw d4,4(a6)
+ stw d4,8(a6)
+ mtctr d1
+ stw d4,12(a6)
+ stwu d4,16(a6)
+
+_copy_elem_lp5:
+ stwu d4,4(a6)
+ bdnz _copy_elem_lp5
+ add a6,a6,d2
+_st_fillr5_array:
+ subic. d0,d0,1
+ bge _fillr5_array_1
+ blr
+
+ csect .yet_args_needed
+yet_args_needed:
+; for more than 4 arguments
+ lwz d1,0(a1)
+ lhz d0,-2(d1)
+ subi d7,d7,3
+ sub. d7,d7,d0
+ blt gc_1
+
+gc_r_1: lwz d3,4(a1)
+ subi d0,d0,1+4
+ lwz a1,8(a1)
+ addi d2,a6,4
+ lwz o0,0(a1)
+ lwz o1,4(a1)
+ stw o0,4(a6)
+ lwz o2,8(a1)
+ stw o1,8(a6)
+ addi a1,a1,12
+ stwu o2,12(a6)
+
+cp_a: lwz o0,0(a1)
+ addi a1,a1,4
+ stwu o0,4(a6)
+ subic. d0,d0,1
+ bge cp_a
+
+ stw a0,4(a6)
+ addi d1,d1,8
+ stw d1,8(a6)
+ addi a0,a6,8
+ stw d3,12(a6)
+ stwu d2,16(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_1: mflr r0
+ bl collect_2
+ b gc_r_1
+
+ csect .yet_args_needed_0
+yet_args_needed_0:
+ subic. d7,d7,2
+ blt gc_20
+gc_r_20: stwu a0,8(a6)
+ lwz d0,0(a1)
+ addi a0,a6,4-8
+ addi d0,d0,8
+ stw d0,4-8(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_20: mflr r0
+ bl collect_2
+ b gc_r_20
+
+ csect .yet_args_needed_1
+yet_args_needed_1:
+ subic. d7,d7,3
+ blt gc_21
+gc_r_21: stwu a0,12(a6)
+ lwz d0,0(a1)
+ addi a0,a6,4-12
+ addi d0,d0,8
+ stw d0,4-12(a6)
+ lwz d1,4(a1)
+ stw d1,8-12(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_21: mflr r0
+ bl collect_2
+ b gc_r_21
+
+ csect .yet_args_needed_2
+yet_args_needed_2:
+ subic. d7,d7,5
+ blt gc_22
+gc_r_22:
+ lwz d0,0(a1)
+ stw a0,8(a6)
+ addi d0,d0,8
+ lwz d2,4(a1)
+ stw d0,12(a6)
+ addi a0,a6,12
+ lwz o0,8(a1)
+ stw d2,16(a6)
+ stwu o0,4(a6)
+ stwu a6,16(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_22: mflr r0
+ bl collect_2
+ b gc_r_22
+
+ csect .yet_args_needed_3
+yet_args_needed_3:
+ subic. d7,d7,6
+ blt gc_23
+gc_r_23:
+ lwz d0,0(a1)
+ stw a0,12(a6)
+ addi d0,d0,8
+ lwz d2,4(a1)
+ stw d0,16(a6)
+ lwz a1,8(a1)
+ stw d2,20(a6)
+ lwz o0,0(a1)
+ lwz o1,4(a1)
+ stwu o0,4(a6)
+ stwu a6,20(a6)
+ addi a0,a6,16-24
+ stw o1,8-24(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_23: mflr r0
+ bl collect_2
+ b gc_r_23
+
+ csect .yet_args_needed_4
+yet_args_needed_4:
+ subic. d7,d7,7
+ blt gc_24
+gc_r_24:
+ lwz d0,0(a1)
+ stw a0,16(a6)
+ addi d0,d0,8
+ lwz d2,4(a1)
+ stw d0,20(a6)
+ lwz a1,8(a1)
+ stw d2,24(a6)
+ lwz o0,0(a1)
+ lwz o1,4(a1)
+ stwu o0,4(a6)
+ stwu a6,24(a6)
+ addi a0,a6,20-28
+ lwz o2,8(a1)
+ stw o1,8-28(a6)
+ stw o2,12-28(a6)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+gc_24: mflr r0
+ bl collect_2
+ b gc_r_24
+
+ csect .repl_args_b
+repl_args_b:
+ cmpwi 0,d0,0
+ ble repl_args_b_1
+
+ subic. d0,d0,1
+ beq repl_args_b_4
+
+ lwz a1,8(a0)
+ subic. d1,d1,2
+ bne repl_args_b_2
+
+ stw a1,0(a4)
+ addi a4,a4,4
+ b repl_args_b_4
+
+repl_args_b_2:
+ slwi d1,d0,2
+ add a1,a1,d1
+ subi d0,d0,1
+repl_args_b_3:
+ lwzu o0,-4(a1)
+ addi a4,a4,4
+ stw o0,0-4(a4)
+ cmpwi 0,d0,0
+ subi d0,d0,1
+ bne repl_args_b_3
+repl_args_b_4:
+ lwz o0,4(a0)
+ addi a4,a4,4
+ stw o0,0-4(a4)
+repl_args_b_1:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .push_arg_b
+push_arg_b:
+ cmplwi 0,d1,2
+ blt push_arg_b_1
+ bne push_arg_b_2
+
+ cmpw 0,d1,d0
+ beq push_arg_b_1
+push_arg_b_2:
+ lwz a0,8(a0)
+ subi d1,d1,2
+push_arg_b_1:
+ slwi d1,d1,2
+ lwzx a0,a0,d1
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .del_args
+del_args:
+ lwz d1,0(a0)
+ sub d1,d1,d0
+ lhz d0,-2(d1)
+ subic. d0,d0,2
+ bge del_args_2
+
+ lwz o0,4(a0)
+ stw d1,0(a1)
+ lwz o1,8(a0)
+ stw o0,4(a1)
+ stw o1,8(a1)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+del_args_2:
+ bne del_args_3
+
+ lwz o0,4(a0)
+ stw d1,0(a1)
+ lwz o1,8(a0)
+ stw o0,4(a1)
+ lwz o1,0(o1)
+ stw o1,8(a1)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+del_args_3:
+ sub. d7,d7,d0
+ blt del_args_gc
+del_args_r_gc:
+ stw d1,0(a1)
+ lwz o0,4(a0)
+ stw a6,8(a1)
+ lwz a0,8(a0)
+ stw o0,4(a1)
+
+del_args_copy_args:
+ lwz o0,0(a0)
+ addi a0,a0,4
+ stw o0,0(a6)
+ addi a6,a6,4
+ subic. d0,d0,1
+ bgt del_args_copy_args
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+del_args_gc:
+ mflr r0
+ bl collect_2
+ b del_args_r_gc
+
+ if 0
+ csect .o__S_P2
+o__S_P2:
+ lwz d0,0(a0)
+ lha d0,-2(d0)
+ cmpwi 0,d0,2
+ lwz a0,8(a0)
+ beq o__S_P2_2
+ lwz a0,0(a0)
+o__S_P2_2:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .ea__S_P2
+ea__S_P2:
+ lea a2,__indirection
+ lwz d0,4(a1)
+ stw a2,0(a1)
+ stw a0,4(a1)
+ mr a1,d0
+ lwz d0,0(a1)
+ andi. r0,d0,2
+ bne ea__S_P2_1
+
+ stw a0,0(a4)
+ addi a4,a4,4
+
+ mtctr d0
+
+ mr a0,a1
+
+ mflr r0
+ stwu r0,-4(sp)
+ bctrl
+ mtlr r0
+
+ mr a1,a0
+ lwzu a0,-4(a4)
+
+ea__S_P2_1:
+ lwz d0,0(a1)
+ lha d0,-2(d0)
+ lwz a1,8(a1)
+ cmpwi 0,d0,2
+ beq ea__S_P2_2
+ lwz a1,0(a1)
+ea__S_P2_2:
+ lwz d0,0(a1)
+ andi. r0,d0,2
+ bne ea__S_P2_3
+
+ subi d0,d0,20
+ mtctr d0
+ bctr
+
+ea__S_P2_3:
+ stw d0,0(a0)
+ lwz g1,4(a1)
+ stw g1,4(a0)
+ lwz g1,8(a1)
+ stw g1,8(a0)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+ endif
+
+ csect .acos_real{PR}
+acos_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .acos
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .asin_real{PR}
+asin_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .asin
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .atan_real{PR}
+atan_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .atan
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .cos_real{PR}
+cos_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .cos
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .sin_real{PR}
+sin_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .sin
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .tan_real{PR}
+tan_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .tan
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .ln_real{PR}
+ln_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .log
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .log10_real{PR}
+log10_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .log10
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .exp_real{PR}
+exp_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .exp
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .sqrt_real{PR}
+sqrt_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f1,f14
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .sqrt
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .pow_real{PR}
+pow_real:
+ mflr r0
+ stwu r0,-4(sp)
+ fmr f2,f14
+ fmr f1,f15
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ bl .pow
+ nop
+#ifdef USE_DCBZ
+ li g2,32
+#endif
+ if MACOSX
+ lwz sp,0(sp)
+ lwz r0,0(sp)
+ else
+ lwz r0,64(sp)
+ endif
+ fmr f14,f1
+ mtlr r0
+ if MACOSX
+ lwz r0,4(sp)
+ addi sp,sp,8
+ else
+ lwz r0,68(sp)
+ addi sp,sp,72
+ endif
+ blr
+
+ csect .entier_real{PR}
+entier_real:
+ lea o0,entier_constants_and_buffers
+ fctiwz f2,f14
+ lfd f1,0(o0)
+ stfd f2,8(o0)
+ fcmpo 0,f14,f1
+ lwz d0,12(o0)
+ bge+ entier_real_2
+
+ lfd f31,24(o0)
+ xoris o1,d0,0x8000
+ stw o1,20(o0)
+ lfd f1,16(o0)
+ fsub f1,f1,f31
+ fcmpo 0,f14,f1
+ beq entier_real_2
+
+ subi d0,d0,1
+entier_real_2:
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .my_pointer_glue{PR}
+ lwz r0,0(r3)
+ stw RTOC,20(SP)
+ mtctr r0
+ lwz RTOC,4(r3)
+ bctr
+
+
+ macro
+ te &address
+ tc &address{TC},&address
+ endm
+
+ toc
+
+ tc INT2{TC},INT+2
+ tc CHAR2{TC},CHAR+2
+ tc BOOL2{TC},BOOL+2
+ tc REAL2{TC},REAL+2
+ tc __STRING__2{TC},__STRING__+2
+ tc __ARRAY__2{TC},__ARRAY__+2
+
+ tc small_integers{TC},small_integers{BS}
+ if 1
+ tc small_integers8{TC},small_integers{BS}+8
+ endif
+ tc stack_p{TC},stack_p{BS}
+ if MACOSX
+ tc end_a_stack{TC},end_a_stack{BS}
+ tc end_b_stack{TC},end_b_stack{BS}
+ endif
+ tc static_characters{TC},static_characters{BS}
+ if 1
+ tc static_characters8{TC},static_characters{BS}+8
+ endif
+ tc sprintf_time_buffer{TC},sprintf_time_buffer{BS}
+ tc sprintf_buffer{TC},sprintf_buffer{BS}
+ tc last_time{TC},last_time{BS}
+ tc heap_size_33{TC},heap_size_33{BS}
+ tc heap_size_129{TC},heap_size_129{BS}
+ tc heap_p{TC},heap_p{BS}
+ tc heap_p1{TC},heap_p1{BS}
+ tc heap_p2{TC},heap_p2{BS}
+ tc heap_mbp{TC},heap_mbp{BS}
+ tc heap_copied_vector_size{TC},heap_copied_vector_size{BS}
+ tc heap_copied_vector{TC},heap_copied_vector{BS}
+ tc halt_sp{TC},halt_sp{BS}
+ tc garbage_collect_time{TC},garbage_collect_time{BS}
+ tc extra_heap{TC},extra_heap{BS}
+ tc extra_heap_size{TC},extra_heap_size{BS}
+ tc execute_time{TC},execute_time{BS}
+ tc basic_only{TC},basic_only{BS}
+ tc alloc_size{TC},alloc_size{BS}
+ tc IO_time{TC},IO_time{BS}
+ if MEASURE_GC
+ tc compact_garbage_collect_time{TC},compact_garbage_collect_time{BS}
+ tc mark_compact_garbage_collect_time{TC},mark_compact_garbage_collect_time{BS}
+ endif
+ tc heap_end_after_copy_gc{TC},heap_end_after_copy_gc{BS}
+ tc caf_listp{TC},caf_listp{BS}
+ tc caf_list{TC},caf_list{BS}
+ tc caf_list4{TC},caf_list{BS}+4
+
+ if EXCEPTIONS
+ tc exception_info{TC},exception_info{BS}
+ endif
+ if FINALIZERS
+ tc finalizer_list{TC},finalizer_list{BS}
+ tc free_finalizer_list{TC},free_finalizer_list{BS}
+ tc __Nil_m8{TC},__Nil-8
+ tc e____system__kFinalizer_2{TC},e____system__kFinalizer+2
+ tc e____system__kFinalizerGCTemp_2{TC},e____system__kFinalizerGCTemp+2
+ endif
+ if MARK_GC
+ te last_heap_free
+ te free_after_mark
+ te bit_counter
+ te zero_bits_before_mark
+ te bit_vector_p
+ te marked_gc_string_1
+ te lazy_array_list
+ if ADJUST_HEAP_SIZE
+ te bit_vector_size
+ te heap_size_multiple
+ te initial_heap_size
+ endif
+ endif
+ if MARK_AND_COPY_GC || !MARK_GC
+ te copy_lp1
+ endif
+ te IO_error_string
+ te __cycle__in__spine
+ te __indirection
+ te stack_size
+ te flags
+ te execution_aborted
+ te heap_size
+ te false_c_string
+ te false_string
+ te file_c_string
+ te garbage_collect_string_1
+ te garbage_collect_string_2
+ te garbage_collect_string_3
+ te heap_end_after_gc
+ te heap_p3
+ te heap_use_after_gc_string_1
+ te heap_use_after_gc_string_2
+ te heap_vector
+ te high_index_string
+ te low_index_string
+ te new_line_string
+ te out_of_memory_string_1
+ te out_of_memory_string_4
+ te print_
+ te printf_int_string
+ te printf_real_string
+ te sprintf_time_string
+ te stack_overflow_string
+ te time_string_1
+ te time_string_2
+ if MEASURE_GC
+ te time_string_2a
+ endif
+ te time_string_3
+ te time_string_4
+ te true_c_string
+ te true_string
+ te zero_length_string
+ te garbage_collect_flag
+ te entier_constants_and_buffers
+
+ if WRITE_HEAP
+ tc first_function{TC},first_function{DS}
+ tc heap2_begin_and_end{TC},heap2_begin_and_end{BS}
+ te min_write_heap_size
+ endif
+ if PROFILE
+ te garbage_collector_name
+ endif
diff --git a/ptrace.a b/ptrace.a
new file mode 100644
index 0000000..e7f5e63
--- /dev/null
+++ b/ptrace.a
@@ -0,0 +1,676 @@
+
+ string asis
+
+ macro
+ lea &r,&a
+ lwz &r,&a{TC}(RTOC)
+ endm
+
+MACOSX set 1
+USE_TEMPORARY_MEMORY set 1
+CHECK_STACK_OVERFLOWS set 0
+MODULE_NAMES set 1
+
+d0: set r24
+d1: set r25
+d2: set r26
+d3: set r27
+d4: set r28
+d5: set r29
+d6: set r30
+d7: set r31
+
+a0: set r23
+a1: set r22
+a2: set r21
+a3: set r20
+a4: set r19
+a5: set r18
+a6: set r17
+
+o0: set r3
+o1: set r4
+o2: set r5
+o3: set r6
+o4: set r7
+o5: set r8
+
+g2: set r9
+g3: set r10
+
+g0: set r11
+g1: set r12
+
+int_reg set r16
+char_reg set r15
+real_reg set r14
+bool_reg set r13
+
+ export init_profiler
+ export profile_r
+ export profile_l
+ export profile_l2
+ export profile_n
+ export profile_n2
+ export profile_s
+ export profile_s2
+ export profile_t
+ export profile_ti
+ export write_profile_information
+ export write_profile_stack
+
+ if USE_TEMPORARY_MEMORY
+ import .TempNewHandle
+ import .TempHLock
+ import .TempHUnlock
+ import .TempDisposeHandle
+ else
+ import .NewPtr
+ endif
+ import __STRING__
+ import writeFC
+ import writeFI
+ import print_error
+ import stack_size
+ import .er_print_string
+ import .er_print_char
+ if CHECK_STACK_OVERFLOWS
+ import .Debugger
+ endif
+
+FunctionProfile: record
+next: ds.l 1
+name: ds.l 1
+ endr
+
+ csect .profile_t
+profile_ti:
+ lea r5,profile_globals
+ b profile_t_
+
+profile_t:
+ mflr r12
+ lea r5,profile_globals
+ mtctr r12
+ mtlr r0
+profile_t_:
+ lwz r6,Globals.stack_pointer(r5)
+ lwzu r4,-4(r6)
+ stw r6,Globals.stack_pointer(r5)
+ bctr
+
+ csect .profile_r
+profile_r:
+ lea r5,profile_globals
+ lwz r6,Globals.stack_pointer(r5)
+ lwzu r4,-4(r6)
+ stw r6,Globals.stack_pointer(r5)
+ blr
+
+ csect .profile_l
+profile_l:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ mtlr r0
+ bctr
+
+ csect .profile_l2
+profile_l2:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+
+ mtlr r0
+ bctr
+
+ csect .profile_n
+profile_n:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ mtlr r0
+ bctr
+
+ csect .profile_n2
+profile_n2:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ mtlr r0
+ bctr
+
+ csect .profile_s2
+profile_s2:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+ stw r4,0(r6)
+ stw r4,4(r6)
+ addi r6,r6,8
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ mtlr r0
+ bctr
+
+ csect .profile_s
+profile_s:
+ mflr r12
+ lea r5,profile_globals
+ lwz r4,0(r3)
+ mtctr r12
+
+ cmpwi 0,r4,0
+ beql allocate_function_profile_record
+
+ lwz r6,Globals.stack_pointer(r5)
+
+ stw r4,0(r6)
+ addi r6,r6,4
+ if CHECK_STACK_OVERFLOWS
+ lwz r12,Globals.end_profile_stack(r5)
+ endif
+ stw r6,Globals.stack_pointer(r5)
+ if CHECK_STACK_OVERFLOWS
+ cmpw r6,r12
+ bge profile_stack_overflow
+ endif
+ mtlr r0
+ bctr
+
+allocate_function_profile_record:
+ lwz r6,Globals.n_free_records_in_block(r5)
+ lwz r4,Globals.last_allocated_block(r5)
+ cmpwi 0,r6,0
+ bne+ no_alloc
+
+ stw r0,-4(sp)
+ stw r3,-8(sp)
+ stw r9,-12(sp)
+ stw r10,-16(sp)
+ mfctr r11
+ stw r11,-20(sp)
+ mflr r12
+ stw r12,-24(sp)
+
+ if USE_TEMPORARY_MEMORY
+ li r3,(512*FunctionProfile)+4
+ else
+ li r3,512*FunctionProfile
+ endif
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+32+28)(sp)
+ else
+ stwu sp,-(64+32)(sp)
+ endif
+ if USE_TEMPORARY_MEMORY
+ bl allocate_temp_memory_handle
+ else
+ bl .NewPtr
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64+32
+ endif
+ and. r4,r3,r3
+
+ lwz r12,-24(sp)
+ lwz r11,-20(sp)
+ mtlr r12
+ lwz r10,-16(sp)
+ mtctr r11
+ lwz r9,-12(sp)
+ lwz r3,-8(sp)
+ lwz r0,-4(sp)
+
+ lea r5,profile_globals
+
+ beq profiler_memory_error
+
+ if USE_TEMPORARY_MEMORY
+ lwz r6,Globals.temp_handle_list(r5)
+ stw r4,Globals.temp_handle_list(r5)
+ lwz r4,0(r4)
+ stw r6,0(r4)
+ addi r4,r4,4
+ endif
+ li r6,512
+ stw r4,Globals.last_allocated_block(r5)
+
+no_alloc:
+ subi r6,r6,1
+ stw r6,Globals.n_free_records_in_block(r5)
+ addi r7,r4,FunctionProfile
+ stw r7,Globals.last_allocated_block(r5)
+
+ lwz r6,Globals.profile_records(r5)
+ li r8,0
+ stw r6,FunctionProfile.next(r4)
+ stw r4,Globals.profile_records(r5)
+ stw r3,FunctionProfile.name(r4)
+
+ stw r4,0(r3)
+ blr
+
+ csect .write_profile_information
+write_profile_information:
+ if USE_TEMPORARY_MEMORY
+ mflr r0
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(96+28)(sp)
+ else
+ stwu sp,-96(sp)
+ endif
+ stw r0,96-4(sp)
+ lea r5,profile_globals
+ lwz r3,Globals.profile_stack_handle(r5)
+ bl free_temp_memory_handle
+
+ lea r5,profile_globals
+
+ stw r31,96-8(sp)
+
+ lwz r31,Globals.temp_handle_list(r5)
+ b free_temp_handles
+
+free_temp_handles_lp:
+ mr r3,r31
+ lwz r31,0(r31)
+ lwz r31,0(r31)
+ bl free_temp_memory_handle
+
+free_temp_handles:
+ cmpwi 0,r31,0
+ bne free_temp_handles_lp
+
+ lwz r31,96-8(sp)
+
+ lwz r0,96-4(sp)
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,96
+ endif
+ mtlr r0
+ endif
+ lwz r0,0(sp)
+ addi sp,sp,4
+ blr
+
+ csect .write_profile_stack
+write_profile_stack:
+ mflr r0
+ lea d0,profile_globals
+ stwu r0,-4(sp)
+ lwz d0,Globals.stack_pointer(d0)
+
+ cmpwi 0,d0,0
+ beq @stack_not_initialised
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ lea o0,stack_trace_string
+ bl .er_print_string
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+ li d2,12
+@write_functions_on_stack
+ lwzu d1,-4(d0)
+ cmpwi 0,d1,0
+ beq @end_profile_stack
+
+ lwz o0,FunctionProfile.name(d1)
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ addi o0,o0,4
+ bl .er_print_string
+ nop
+ li o0,13
+ bl .er_print_char
+ nop
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+
+ subic. d2,d2,1
+ if 0
+ b @write_functions_on_stack
+ else
+ bne @write_functions_on_stack
+ endif
+
+@end_profile_stack:
+@stack_not_initialised:
+ lwz r0,0(sp)
+ mtlr r0
+ lwz r0,4(sp)
+ addi sp,sp,8
+ blr
+
+ csect .init_profiler
+init_profiler:
+ if 0
+ mflr r0
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+
+ bl .Debugger
+ nop
+
+ lwz r0,64-4(sp)
+ addi sp,sp,64
+ mtlr r0
+ endif
+
+ mflr r0
+ stwu r0,-4(sp)
+
+ if 1
+ lea r3,stack_size
+ lwz r3,0(r3)
+ else
+ li r3, (512*1024) % 65536
+ addis r3,r3,(512*1024) / 65536
+ endif
+
+ if MACOSX
+ mr g0,sp
+ ori sp,sp,28
+ stwu g0,-(64+28)(sp)
+ else
+ stwu sp,-64(sp)
+ endif
+ if USE_TEMPORARY_MEMORY
+ bl allocate_temp_memory_handle
+ else
+ bl .NewPtr
+ nop
+ endif
+ if MACOSX
+ lwz sp,0(sp)
+ else
+ addi sp,sp,64
+ endif
+ lea r5,profile_globals
+
+ and. r9,r3,r3
+ beq init_profiler_error
+
+ if USE_TEMPORARY_MEMORY
+ stw r9,Globals.profile_stack_handle(r5)
+ lwz r9,0(r9)
+ li r0,0
+ stw r0,Globals.temp_handle_list(r5)
+ endif
+ if CHECK_STACK_OVERFLOWS
+ if 1
+ lea r3,stack_size
+ lwz r3,0(r3)
+ else
+ li r3, (512*1024) % 65536
+ addis r3,r3,(512*1024) / 65536
+ endif
+ add r3,r3,r9
+ stw r3,Globals.end_profile_stack(r5)
+ endif
+ lea r3,start_string
+ bl allocate_function_profile_record
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+ mtlr r0
+
+ li r0,0
+ stw r4,4(r9)
+ stw r0,0(r9)
+ addi r9,r9,8
+ stw r9,Globals.stack_pointer(r5)
+ stw d7,Globals.n_words_free(r5)
+
+ lwz r0,0(sp)
+ addi sp,sp,4
+
+ blr
+
+ if USE_TEMPORARY_MEMORY
+allocate_temp_memory_handle:
+ mflr r0
+ stw r31,-4(sp)
+ stw r0,8(sp)
+ stwu sp,-96(sp)
+
+ addi r4,sp,56
+ bl .TempNewHandle
+ nop
+
+ mr. r31,r3
+ beq return_r31
+
+ addi r4,sp,56
+ bl .TempHLock
+ nop
+
+ lha r0,56(sp)
+ cmpwi r0,0
+ beq+ return_r31
+
+ mr r3,r31
+ addi r4,sp,56
+ bl .TempDisposeHandle
+ nop
+
+ li r31,0
+return_r31:
+ lwz r0,104(sp)
+ mr r3,r31
+ mtlr r0
+ addi sp,sp,96
+ lwz r31,-4(sp)
+ blr
+
+free_temp_memory_handle:
+ mflr r0
+ stw r3,-4(sp)
+ stw r0,8(sp)
+ stwu sp,-96(sp)
+
+ addi r4,sp,56
+ bl .TempHUnlock
+ nop
+
+ lwz r3,96-4(sp)
+ addi r4,sp,56
+ bl .TempDisposeHandle
+ nop
+
+ lwz r0,104(sp)
+ addi sp,sp,96
+ mtlr r0
+ blr
+ endif
+
+init_profiler_error:
+ lea o0,not_enough_memory_for_profile_stack
+ lea r5,profile_globals
+ li r4,0
+ stw r4,Globals.stack_pointer(r5)
+ b print_error
+profiler_memory_error:
+ lea o0,not_enough_memory_for_profiler
+ b print_error
+ if CHECK_STACK_OVERFLOWS
+profile_stack_overflow:
+ mflr r0
+ stw r0,-4(sp)
+ stwu sp,-64(sp)
+
+ bl .Debugger
+ nop
+
+ lwz r0,64-4(sp)
+ addi sp,sp,64
+ mtlr r0
+ b profile_stack_overflow
+ endif
+
+
+ csect data{RW}
+Globals: record
+n_free_records_in_block:ds.l 1 ; 0 n free records in block
+last_allocated_block: ds.l 1 ; 4 latest allocated block
+profile_records: ds.l 1 ; 8 profile record list
+stack_pointer: ds.l 1 ; 12 stack pointer
+n_words_free: ds.l 1
+ if USE_TEMPORARY_MEMORY
+temp_handle_list ds.l 1
+profile_stack_handle ds.l 1
+ endif
+ if CHECK_STACK_OVERFLOWS
+end_profile_stack ds.l 1
+ endif
+ endr
+
+ align 2
+profile_globals: ds Globals
+
+ align 2
+ if MODULE_NAMES
+m_system:
+ dc.l 6
+ dc.b 'System'
+ dc.b 0,0
+ dc.l m_system
+ endif
+start_string:
+ dc.l 0
+ dc.b 'start'
+ dc.b 0
+ align 2
+not_enough_memory_for_profile_stack:
+ dc.b 'not enough memory for profile stack'
+ dc.b 13
+ dc.b 0
+not_enough_memory_for_profiler:
+ dc.b 'not enough memory for profiler'
+ dc.b 13
+ dc.b 0
+stack_trace_string:
+ dc.b 'Stack trace:'
+ dc.b 13
+ dc.b 0
+ align 2
+
+ macro
+ te &address
+ tc &address{TC},&address
+ endm
+
+ toc
+
+ te profile_globals
+ te not_enough_memory_for_profile_stack
+ te not_enough_memory_for_profiler
+ te start_string
+ te stack_trace_string
+ te stack_size