$OpenBSD: patch-src_installers_80x86_openbsd_assembler_c,v 1.1.1.1 2003/08/04 23:37:06 avsm Exp $
--- src/installers/80x86/openbsd/assembler.c.orig	2003-02-10 05:34:39.000000000 -0500
+++ src/installers/80x86/openbsd/assembler.c	2003-08-03 11:23:29.000000000 -0400
@@ -66,26 +66,22 @@
 #include "localflags.h"
 #include "basicread.h"
 #include "coder.h"
-
+#include "exp.h"
+#include "shapemacs.h"
+#include "flags.h"
+#include "assembler.h"
+#include "instr.h"
+#include "instr386.h"
+#include "xalloc.h"
+#include "install_fns.h"
+#include <string.h>
 
 /* PROCEDURES */
 
 void
 dot_align(int n)
 {
-	if (n == 1)
-		return;
 	outs(".align ");
-	switch (n) {
-    case 16:
-		n = 4; break;
-    case 8:
-		n = 3; break;
-    case 4:
-		n = 2; break;
-    default:
-		n = 1; break;
-	};
 	outn((long)n);
 	outnl();
 	return;
@@ -117,32 +113,34 @@ void
 align_label(int f, exp jr)
 {
 	if (is80486 && !is80586 && ptno(jr) != last_jump_label) {
-		if (f == 1)	/* repeat jump */
-			outs(".align 3,0x90");
-		if (f == 2)	/* preceded by a jmp or ret */
-			outs(".align 4,0x90");
-		if (f == 3)
-			outs(".align 2,0x90");
-		outs("\n");
-	};
-	if (is80586 && ptno(jr) != last_jump_label)  {
-		if (f >= 1 && f <= 3)
-			outs(".align 2,0x90\n");
-	};
+		if (f == 1)     /* repeat jump */
+			outs(".align 4");
+		if (f == 2)     /* preceded by a jmp or ret */
+			outs(".align 16");
+			outs("\n");
+	}
 	return;
 }
 
 void
 eval_postlude(char * s, exp c)
 {
-	UNUSED(s); UNUSED(c);
+	outs(".size ");
+	outs (s);
+	outs (",");
+	outn((long)(shape_size(sh(c))+7)/8);
+	outnl();
+	outs(".type ");
+	outs (s);
+	outs (",@object");
+	outnl();
 	return;
 }
 
 void
 out_readonly_section()
 {
-	outs (".text");
+	outs (".section .rodata");
 	return;
 }
 
@@ -179,9 +177,28 @@ out_bss(char * id, shape sha)
 	return;
 }
 
+static int pic_label;
+
 void
 pic_prelude()
 {
+	int n = next_lab();
+	pic_label = n;
+	outs(" call ");
+	outs(local_prefix);
+	outn((long)n);
+	outnl();
+	outs(local_prefix);
+	outn((long)n);
+	outs(":");
+	outnl();
+	outs(" popl %ebx");
+	outnl();
+	outs(" addl $_GLOBAL_OFFSET_TABLE_+[.-");
+	outs(local_prefix);
+	outn((long)n);
+	outs("],%ebx");
+	outnl();
 	return;
 }
 
@@ -195,15 +212,32 @@ out_rename(char * oldid, char * newid)
 void
 out_switch_jump(int tab, where a, int min)
 {
-	outs (" jmp *");
+	if (min != 0) {
+		sub (slongsh, mw(zeroe,min), a, reg0);
+		a = reg0;
+	}
+	if (eq_where (a, reg0)) {
+		outs (" movl ");
+	}
+	else {
+		outs (" movl %ebx,%eax");
+		outnl();
+		outs (" subl ");
+	}
 	outs(local_prefix);
 	outn((long)tab);
-	outs("-");
-	outn((long)(4 * min));
-	outs ("(,");
+	outs("@GOTOFF(%ebx,");
 	operand (32, a, 1, 0);
-	outs (",4)");
-	outnl ();
+	outs(",4),%eax");
+	outnl();
+	if (eq_where (a, reg0)) {
+		outs (" subl %ebx,%eax");
+		outnl();
+		outs (" negl %eax");
+		outnl();
+	}
+	outs(" jmp *%eax");
+	outnl();
 	return;
 }
 
@@ -224,15 +258,19 @@ out_switch_table(int tab, int min, int m
 	for (i = min; i <= max; ++i) {
 		outs (".long ");
 		if (v[i - min] != -1)  {
+			outs(" _GLOBAL_OFFSET_TABLE_+[.-");
 			outs(local_prefix);
 			outn ((long)v[i - min]);
+			outs("]");
 		}
 		else  {
 			if (absent == -1)
 				outn ((long)0);
 			else {
+				outs(" _GLOBAL_OFFSET_TABLE_+[.-");
 				outs(local_prefix);
 				outn ((long)absent);
+				outs("]");
 			};
 		};
 		outnl ();
@@ -244,7 +282,7 @@ out_switch_table(int tab, int min, int m
 void
 proc_size(char * s)
 {
-	outs(".align 4");
+	outs(".align 16");
 	outnl();
 	outs(".size ");
 	outs(s);
@@ -304,8 +342,10 @@ outdivsym()
 void
 out_initialiser(char* id)
 {
-	outs(".stabs \"___TDFI_LIST__\",22,0,0,");
+	outs (".section .init\n");
+	outs (" call ");
 	outs (id);
+	outs ("@PLT");
 	outnl ();
 	outnl ();
 	return;
@@ -339,8 +379,7 @@ out_main_postlude()
 {
 	char * sdummy = "Idummy";
 	char * pdummy = (char *) xcalloc (((int)strlen(local_prefix) +
-									   (int)strlen(sdummy) + 1),
-									  sizeof (char));
+			   (int)strlen(sdummy) + 1), sizeof (char));
 	strcpy (pdummy, local_prefix);
 	strcat (pdummy, sdummy);
 	outs (".text\n");
