commit
						34c4cfee8f
					
				
					 33 changed files with 1117 additions and 809 deletions
				
			
		|  | @ -8,6 +8,7 @@ vars.plats = { | |||
| 	"cpm", | ||||
| 	"linux386", | ||||
| 	"linux68k", | ||||
| 	"linuxppc", | ||||
| 	"pc86", | ||||
| 	"rpi", | ||||
| } | ||||
|  |  | |||
|  | @ -8,7 +8,8 @@ | |||
| program hilo(input, output); | ||||
| 
 | ||||
| type | ||||
| 	string = array [0..255] of char; | ||||
| 	string = packed array [0..255] of char; | ||||
| 	charstar = packed array [0..0] of char; | ||||
| 	 | ||||
| var | ||||
| 	playing : Boolean; | ||||
|  | @ -34,18 +35,18 @@ function random(range : integer) : integer; | |||
|   that conflicts with a Pascal keyword. Luckily there's a private function | ||||
|   uread() in the ACK Pascal library that we can use instead. } | ||||
|    | ||||
| function uread(fd : integer; var buffer : char; count : integer) : integer; | ||||
| function uread(fd : integer; var buffer : charstar; count : integer) : integer; | ||||
| 	extern; | ||||
| 
 | ||||
| function readchar : char; | ||||
| 	var | ||||
| 		c : char; | ||||
| 		c : charstar; | ||||
| 		dummy : integer; | ||||
| 		 | ||||
| 	begin | ||||
| 		c := chr(0); | ||||
| 		c[0] := chr(0); | ||||
| 		dummy := uread(0, c, 1); | ||||
| 		readchar := c; | ||||
| 		readchar := c[0]; | ||||
| 	end; | ||||
| 	 | ||||
| procedure readstring(var buffer : string; var length : integer); | ||||
|  |  | |||
							
								
								
									
										2
									
								
								h/out.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								h/out.h
									
										
									
									
									
								
							|  | @ -66,7 +66,7 @@ struct outname { | |||
| #define RELO2	   2			/* 2 bytes */ | ||||
| #define RELO4	   3			/* 4 bytes */ | ||||
| #define RELOPPC    4            /* PowerPC 26-bit address */ | ||||
| #define RELOH2     5            /* write top 2 bytes of 4 byte word */ | ||||
| /* relo 5 is unused */ | ||||
| #define RELOVC4    6            /* VideoCore IV address in 32-bit instruction */ | ||||
| 
 | ||||
| #define RELPC	0x2000			/* pc relative */ | ||||
|  |  | |||
|  | @ -80,7 +80,7 @@ | |||
| %token <y_word> OP_TO_RA_RB | ||||
| %token <y_word> OP_TO_RA_SI | ||||
| 
 | ||||
| %token <y_word> OP_la | ||||
| %token <y_word> OP_LI32 | ||||
| 
 | ||||
| /* Other token types */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -98,7 +98,7 @@ | |||
| 
 | ||||
| /* Special instructions */ | ||||
| 
 | ||||
| 0,     OP_la,                 0,                                       "la", | ||||
| 0,     OP_LI32,               0,                                       "li32", | ||||
| 
 | ||||
| /* Branch processor instructions (page 20) */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -58,6 +58,7 @@ operation | |||
| 	| OP_LEV               u7                         { emit4($1 | ($2<<5)); } | ||||
| 	| OP_LIA               lia                        { emit4($1 | $2); } | ||||
| 	| OP_LIL               lil                        { emit4($1 | $2); } | ||||
| 	| OP_LI32              li32                       /* emitted in subrule */ | ||||
| 	; | ||||
| 
 | ||||
| c | ||||
|  | @ -66,26 +67,12 @@ c | |||
| 	; | ||||
| 	 | ||||
| e16 | ||||
| 	: '<' expr | ||||
| 	: absexp | ||||
| 	{ | ||||
| 		DOTVAL += 2; | ||||
| 		newrelo($2.typ, RELOH2 | FIXUPFLAGS); | ||||
| 		DOTVAL -= 2; | ||||
| 		$$ = ($2.val >> 16) & 0xFFFF; | ||||
| 	} | ||||
| 	| '>' expr | ||||
| 	{ | ||||
| 		DOTVAL += 2; | ||||
| 		newrelo($2.typ, RELO2 | FIXUPFLAGS); | ||||
| 		DOTVAL -= 2; | ||||
| 		$$ = $2.val & 0xFFFF; | ||||
| 	} | ||||
| 	| expr | ||||
| 	{ | ||||
| 		DOTVAL += 2; | ||||
| 		newrelo($1.typ, RELO2 | FIXUPFLAGS); | ||||
| 		DOTVAL -= 2; | ||||
| 		$$ = $1.val & 0xFFFF; | ||||
| 		/* Allow signed or unsigned 16-bit values. */ | ||||
| 		if (($1 < -0x8000) || ($1 > 0xffff)) | ||||
| 			serror("16-bit value out of range"); | ||||
| 		$$ = (uint16_t) $1; | ||||
| 	} | ||||
| 	; | ||||
| 		 | ||||
|  | @ -206,6 +193,15 @@ bda | |||
| 	} | ||||
| 	; | ||||
| 	 | ||||
| li32 | ||||
| 	: GPR ',' expr | ||||
| 	{ | ||||
| 		newrelo($3.typ, RELOPPC | FIXUPFLAGS); | ||||
| 		emit4((15<<26) | ($1<<21) | (0<<16)  | ($3.val >> 16)); /* addis */ | ||||
| 		emit4((24<<26) | ($1<<21) | ($1<<16) | ($3.val & 0xffff)); /* ori */ | ||||
| 	} | ||||
| 	; | ||||
| 
 | ||||
| lil | ||||
| 	: expr | ||||
| 	{ | ||||
|  |  | |||
|  | @ -13,11 +13,14 @@ | |||
| !    r3 = ptr to descriptor | ||||
| !    r4 = index | ||||
| !    r5 = address of array | ||||
| ! Yields: | ||||
| !    r3 = address of element | ||||
| !    r0 = size of element (used by .lar4, .sar4) | ||||
| ! Preserves r10 for .lar4, .sar4 | ||||
| 
 | ||||
| .define .aar4 | ||||
| .aar4: | ||||
| 	addis r0, r0, <.trap_earray | ||||
| 	ori r0, r0, >.trap_earray | ||||
| 	li32 r0, .trap_earray | ||||
| 	mtspr ctr, r0            ! load CTR with trap address | ||||
| 
 | ||||
| 	lwz r0, 0(r3) | ||||
|  |  | |||
							
								
								
									
										13
									
								
								mach/powerpc/libem/build.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								mach/powerpc/libem/build.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| for _, plat in ipairs(vars.plats) do | ||||
| 	acklibrary { | ||||
| 		name = "lib_"..plat, | ||||
| 		srcs = { | ||||
| 			"./*.s", | ||||
| 		}, | ||||
| 		vars = { plat = plat }, | ||||
| 		deps = { | ||||
| 			"h+emheaders" | ||||
| 		} | ||||
| 	} | ||||
| end | ||||
| 
 | ||||
|  | @ -13,15 +13,15 @@ | |||
| 
 | ||||
| .define .cfu8 | ||||
| .cfu8: | ||||
| 	la(r3, .fd_00000000) | ||||
| 	li32 r3, .fd_00000000 | ||||
| 	lfd f0, 0(r3)            ! f0 = 0.0 | ||||
| 	 | ||||
| 	lfd f1, 0(sp)            ! value to be converted | ||||
| 
 | ||||
| 	la(r3, .fd_FFFFFFFF) | ||||
| 	li32 r3, .fd_FFFFFFFF | ||||
| 	lfd f3, 0(r3)            ! f3 = 0xFFFFFFFF	 | ||||
| 
 | ||||
| 	la(r3, .fd_80000000) | ||||
| 	li32 r3, .fd_80000000 | ||||
| 	lfd f4, 0(r3)            ! f4 = 0x80000000 	 | ||||
| 	 | ||||
| 	fsel f2, f1, f1, f0 | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ | |||
| 	 | ||||
| 	lfd f0, 0(sp)            ! load value | ||||
| 
 | ||||
| 	la (r3, pivot) | ||||
| 	li32 r3, pivot | ||||
| 	lfd f1, 0(r3)            ! load pivot value | ||||
| 	fsub f0, f0, f1          ! adjust | ||||
| 	                          | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ | |||
| 	 | ||||
| 	lfd f0, 0(sp)            ! load value | ||||
| 	 | ||||
| 	la (r3, pivot) | ||||
| 	li32 r3, pivot | ||||
| 	lfd f1, 0(r3)            ! load pivot value | ||||
| 	fsub f0, f0, f1          ! adjust | ||||
| 	                          | ||||
|  |  | |||
|  | @ -1,46 +0,0 @@ | |||
| /*
 | ||||
|  * $Source$ | ||||
|  * $State$ | ||||
|  * $Revision$ | ||||
|  */ | ||||
| 
 | ||||
| /* no headers allowed! */ | ||||
| 
 | ||||
| /* Given a double, calculates the mantissa and exponent.
 | ||||
|  *  | ||||
|  * This function is intended to be called internally by the code generator, | ||||
|  * so the calling convention is odd. | ||||
|  */ | ||||
| 
 | ||||
| int __fef8(double* fp) | ||||
| { | ||||
| 	double f = *fp; | ||||
| 	int exponent, sign; | ||||
| 
 | ||||
| 	if (f == 0.0) | ||||
| 		return 0; | ||||
| 		 | ||||
| 	if (f < 0.0) | ||||
| 	{ | ||||
| 		sign = -1; | ||||
| 		f = -f; | ||||
| 	} | ||||
| 	else | ||||
| 		sign = 0; | ||||
| 	 | ||||
| 	exponent = 0; | ||||
| 	while (f >= 1.0) | ||||
| 	{ | ||||
| 		f /= 2.0; | ||||
| 		exponent++; | ||||
| 	} | ||||
| 	 | ||||
| 	while (f < 0.5) | ||||
| 	{ | ||||
| 		f *= 2.0; | ||||
| 		exponent--; | ||||
| 	} | ||||
| 	 | ||||
| 	*fp = (sign) ? -f : f; | ||||
| 	return exponent; | ||||
| } | ||||
							
								
								
									
										58
									
								
								mach/powerpc/libem/fef8.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								mach/powerpc/libem/fef8.s
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| #include "powerpc.h" | ||||
| 
 | ||||
| .sect .text | ||||
| 
 | ||||
| ! Split a double-precision float into fraction and exponent, like | ||||
| ! frexp(3) in C.  On entry: | ||||
| !  r3 = float, high word (bits 0..31) | ||||
| !  r4 = float, low word (bits 32..63) | ||||
| ! Yields: | ||||
| !  r3 = fraction, high word (bits 0..31) | ||||
| !  r4 = fraction, low word (bits 32..63) | ||||
| !  r5 = exponent | ||||
| ! Kills: cr0 f0 f1 r6 r7 | ||||
| 
 | ||||
| .define .fef8 | ||||
| .fef8: | ||||
| 	! IEEE double-precision format: | ||||
| 	!   sign  exponent  fraction | ||||
| 	!   0     1..11     12..63 | ||||
| 	rlwinm r6, r3, 12, 21, 31	! r6 = IEEE exponent | ||||
| 	addis r7, r0, 0x7ff0		! r7 = exponent mask | ||||
| 	addi r5, r6, -1022		! r5 = true exponent | ||||
| 	cmpi cr0, 0, r6, 2047 | ||||
| 	bclr IFTRUE, EQ, 0		! return if infinity or NaN | ||||
| 	cmpi cr0, 0, r6, 0 | ||||
| 	bc IFFALSE, EQ, 1f		! jump if normalized number | ||||
| 
 | ||||
| 	! Got denormalized number or zero, probably zero. | ||||
| 	rlwinm r6, r3, 0, 12, 31 | ||||
| 	addi r5, r0, 0			! r5 = true exponent = 0 | ||||
| 	or. r6, r6, r4			! r6 = high|low fraction | ||||
| 	bclr IFTRUE, EQ, 0		! return if zero | ||||
| 
 | ||||
| 	! Got denormalized number, not zero. | ||||
| 	stwu r4, -4(sp) | ||||
| 	stwu r3, -4(sp) | ||||
| 	li32 r6, _2_64 | ||||
| 	lfd f0, 0(sp) | ||||
| 	lfd f1, 0(r6) | ||||
| 	fmul f0, f0, f1			! multiply it by 2**64 | ||||
| 	stfd f0, 0(sp) | ||||
| 	lwz r3, 0(sp) | ||||
| 	lwz r4, 4(sp) | ||||
| 	rlwinm r6, r3, 12, 21, 31	! r6 = IEEE exponent | ||||
| 	addi sp, sp, 8 | ||||
| 	addi r5, r6, -1022 - 64		! r5 = true exponent | ||||
| 1: | ||||
| 	! Put fraction in [0.5, 1) or (-1, -0.5] by setting its | ||||
| 	! exponent to true 0, IEEE 1022. | ||||
| 	andc r3, r3, r7			! clear old exponent | ||||
| 	oris r3, r3, 1022 << 4		! set new exponent | ||||
| 	bclr ALWAYS, 0, 0 | ||||
| 
 | ||||
| .sect .rom | ||||
| _2_64: | ||||
| 	! (double) 2**64 | ||||
| 	.data4 0x43f00000
 | ||||
| 	.data4 0x00000000
 | ||||
|  | @ -1,38 +1,71 @@ | |||
| # | ||||
| ! $Source$ | ||||
| ! $State$ | ||||
| ! $Revision$ | ||||
| 
 | ||||
| #include "powerpc.h" | ||||
| 
 | ||||
| .sect .text | ||||
| 
 | ||||
| ! Multiplies two floats, and returns the fraction and integer. | ||||
| ! Multiplies two double-precision floats, then splits the product into | ||||
| ! integer and fraction, like modf(3) in C.  On entry: | ||||
| !  f1 = float | ||||
| !  f2 = other float | ||||
| ! Yields: | ||||
| !  f1 = fraction | ||||
| !  f2 = integer | ||||
| ! Kills: cr0 f1 f2 r3 r4 r5 r6 | ||||
| 
 | ||||
| .define .fif8 | ||||
| .fif8: | ||||
| 	lfd f0, 8(sp) | ||||
| 	lfd f1, 0(sp) | ||||
| 	fmul f0, f0, f1 | ||||
| 	fabs f1, f0              ! f0 = result | ||||
| 	fmul f1, f1, f2 | ||||
| 	stfdu f1, -8(sp)		! push f1 = product | ||||
| 	lwz r3, 0(sp)			! r3 = high word | ||||
| 	lwz r4, 4(sp)			! r4 = low word | ||||
| 
 | ||||
| 	! The following chunk does f1 = floor(f1). See page 158 of the book. | ||||
| 	! IEEE double-precision format: | ||||
| 	!   sign  exponent  fraction | ||||
| 	!   0     1..11     12..63 | ||||
| 	! Subtract 1023 from the IEEE exponent.  If the result is from | ||||
| 	! 0 to 51, then the IEEE fraction has that many integer bits. | ||||
| 	! (IEEE has an implicit 1 before its fraction.  If the IEEE | ||||
| 	! fraction has 0 integer bits, we still have an integer.) | ||||
| 	rlwinm r5, r3, 12, 21, 31	! r5 = IEEE exponent | ||||
| 	addic. r5, r5, -1023		! r5 = nr of integer bits | ||||
| 	bc IFTRUE, LT, no_int | ||||
| 	cmpi cr0, 0, r5, 21 | ||||
| 	bc IFTRUE, LT, small_int | ||||
| 	cmpi cr0, 0, r5, 52 | ||||
| 	bc IFTRUE, LT, big_int | ||||
| 
 | ||||
| 	mtfsfi cr7, 3              ! set rounding mode to -inf. | ||||
| 	mtfsb0 23 | ||||
| 	fctid f2, f1 | ||||
| 	fcfid f2, f2 | ||||
| 	mcrfs cr7, cr5 | ||||
| 	bc IFFALSE, 31, toobig | ||||
| 	fmr f1, f2 | ||||
| toobig: | ||||
| 	! f1 is an integer without fraction.  Jump to calculate | ||||
| 	! fraction f1 = f2 - f1.  It will be zero (or perhaps NaN). | ||||
| 	fmr f2, f1 | ||||
| 	b subtract | ||||
| 
 | ||||
| 	fabs f2, f1              ! f2 = fabs(f1) | ||||
| 	fsub f2, f2, f1 | ||||
| 	stfd f2, 8(sp) | ||||
| no_int: | ||||
| 	! f1 is a fraction without integer. | ||||
| 	fsub f2, f1, f1			! integer = zero | ||||
| 	b done | ||||
| 
 | ||||
| 	fneg f2, f1 | ||||
| 	fsel f2, f0, f1, f2 | ||||
| 	stfd f2, 0(sp) | ||||
| small_int: | ||||
| 	! f1 has r5 = 0 to 20 integer bits in the IEEE fraction. | ||||
| 	! High word has 20 - r5 fraction bits. | ||||
| 	addi r6, r0, 20 | ||||
| 	subf r6, r5, r6 | ||||
| 	srw r3, r3, r6 | ||||
| 	addi r4, r0, 0			! clear low word | ||||
| 	slw r3, r3, r6			! clear fraction in high word | ||||
| 	b move_int | ||||
| 
 | ||||
| big_int: | ||||
| 	! f1 has r5 = 21 to 51 to integer bits. | ||||
| 	! Low word has 52 - r5 fraction bits. | ||||
| 	addi r6, r0, 52 | ||||
| 	subf r6, r5, r6 | ||||
| 	srw r4, r4, r6 | ||||
| 	slw r4, r4, r6			! clear fraction in low word | ||||
| move_int: | ||||
| 	stw r3, 0(sp) | ||||
| 	stw r4, 4(sp) | ||||
| 	lfd f2, 0(sp)			! f2 = integer | ||||
| subtract: | ||||
| 	fsub f1, f1, f2			! fraction = value - integer | ||||
| done: | ||||
| 	addi sp, sp, 8			! restore stack pointer | ||||
| 	bclr ALWAYS, 0, 0 | ||||
|  |  | |||
							
								
								
									
										43
									
								
								mach/powerpc/libem/lar4.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								mach/powerpc/libem/lar4.s
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| # | ||||
| #include "powerpc.h" | ||||
| 
 | ||||
| .sect .text | ||||
| 
 | ||||
| ! Load from bounds-checked array. | ||||
| ! | ||||
| ! On entry: | ||||
| !    r3 = ptr to descriptor | ||||
| !    r4 = index | ||||
| !    r5 = address of array | ||||
| 
 | ||||
| .define .lar4 | ||||
| .lar4: | ||||
| 	mfspr r10, lr | ||||
| 	bl .aar4 | ||||
| 	mtspr lr, r10 | ||||
| 	! r3 = ptr to element | ||||
| 	! r0 = size of element | ||||
| 
 | ||||
| 	cmpi cr0, 0, r0, 1 | ||||
| 	bc IFFALSE, EQ, 1f | ||||
| 	! Load 1 byte. | ||||
| 	lbz r4, 0(r3) | ||||
| 	stwu r4, -4(sp) | ||||
| 	bclr ALWAYS, 0, 0 | ||||
| 1: | ||||
| 	cmpi cr0, 0, r0, 2 | ||||
| 	bc IFFALSE, EQ, 2f | ||||
| 	! Load 2 bytes. | ||||
| 	lhz r4, 0(r3) | ||||
| 	stwu r4, -4(sp) | ||||
| 	bclr ALWAYS, 0, 0 | ||||
| 2: | ||||
| 	! Load r0 bytes, where r0 must be a positive multiple of 4. | ||||
| 	subf sp, r0, sp		! move stack pointer down | ||||
| 	or r5, r0, r0		! index r5 = length r0 | ||||
| 3: | ||||
| 	addic. r5, r5, -4	! r5 -= 4 | ||||
| 	lwzx r4, r5, r3 | ||||
| 	stwx r4, r5, sp | ||||
| 	bc IFTRUE, GT, 3b	! loop if r5 > 0 | ||||
| 	bclr ALWAYS, 0, 0 | ||||
|  | @ -20,4 +20,3 @@ | |||
| #define EQ 2 | ||||
| #define OV 3 | ||||
| 	 | ||||
| #define la(reg, val) addis reg, r0, <val; ori reg, reg, >val | ||||
|  |  | |||
							
								
								
									
										45
									
								
								mach/powerpc/libem/sar4.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								mach/powerpc/libem/sar4.s
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| # | ||||
| #include "powerpc.h" | ||||
| 
 | ||||
| .sect .text | ||||
| 
 | ||||
| ! Store to bounds-checked array. | ||||
| ! | ||||
| ! On entry: | ||||
| !    r3 = ptr to descriptor | ||||
| !    r4 = index | ||||
| !    r5 = address of array | ||||
| 
 | ||||
| .define .sar4 | ||||
| .sar4: | ||||
| 	mfspr r10, lr | ||||
| 	bl .aar4 | ||||
| 	mtspr lr, r10 | ||||
| 	! r3 = ptr to element | ||||
| 	! r0 = size of element | ||||
| 
 | ||||
| 	cmpi cr0, 0, r0, 1 | ||||
| 	bc IFFALSE, EQ, 1f | ||||
| 	! Store 1 byte. | ||||
| 	lwz r4, 0(sp) | ||||
| 	addi sp, sp, 4 | ||||
| 	stb r4, 0(r3) | ||||
| 	bclr ALWAYS, 0, 0 | ||||
| 1: | ||||
| 	cmpi cr0, 0, r0, 2 | ||||
| 	bc IFFALSE, EQ, 2f | ||||
| 	! Store 2 bytes. | ||||
| 	lwz r4, 0(sp) | ||||
| 	addi sp, sp, 4 | ||||
| 	sth r4, 0(r3) | ||||
| 	bclr ALWAYS, 0, 0 | ||||
| 2: | ||||
| 	! Store r0 bytes, where r0 must be a positive multiple of 4. | ||||
| 	or r5, r0, r0		! index r5 = length r0 | ||||
| 3: | ||||
| 	addic. r5, r5, -4	! r5 -= 4 | ||||
| 	lwzx r4, r5, sp | ||||
| 	stwx r4, r5, r3 | ||||
| 	bc IFTRUE, GT, 3b	! loop if r5 > 0 | ||||
| 	add sp, r0, sp		! move stack pointer up | ||||
| 	bclr ALWAYS, 0, 0 | ||||
							
								
								
									
										8
									
								
								mach/powerpc/libend/build.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								mach/powerpc/libend/build.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| for _, plat in ipairs(vars.plats) do | ||||
| 	acklibrary { | ||||
| 		name = "lib_"..plat, | ||||
| 		srcs = { "./*.s" }, | ||||
| 		vars = { plat = plat }, | ||||
| 	} | ||||
| end | ||||
| 
 | ||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -909,23 +909,6 @@ normalfailed:	if (stackpad!=tokpatlen) { | |||
| 
 | ||||
| 	break; | ||||
|     } | ||||
| #endif | ||||
| #ifdef USE_NOFRAMEPOINTER | ||||
| 	case DO_STACKADJUST: { | ||||
| 	result_t result; | ||||
| 	int nodeno; | ||||
| 	 | ||||
| 	DEBUG("STACKADJUST"); | ||||
| 	/* The offset is an expression, which we need to evaluate. */ | ||||
| 	 | ||||
| 	getint(nodeno,codep); | ||||
| 	compute(&enodes[nodeno], &result); | ||||
| 	assert(result.e_typ==EV_INT); | ||||
| 	 | ||||
| 	if (toplevel) | ||||
| 		stackoffset += result.e_v.e_con; | ||||
| 	break; | ||||
| 	} | ||||
| #endif | ||||
| 	} | ||||
| 	} | ||||
|  |  | |||
|  | @ -20,9 +20,6 @@ extern rl_p curreglist;                 /* side effect of findcoerc() */ | |||
| #ifndef NDEBUG | ||||
| extern int Debug;                       /* on/off debug printout */ | ||||
| #endif | ||||
| #ifdef USE_NOFRAMEPOINTER | ||||
| extern int stackoffset;                 /* offset from localbase to sp */ | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Next descriptions are external declarations for tables created | ||||
|  |  | |||
|  | @ -42,6 +42,13 @@ begtext: | |||
| 	 | ||||
| 	b __m_a_i_n | ||||
| 
 | ||||
| ! Define symbols at the beginning of our various segments, so that we can find | ||||
| ! them. (Except .text, which has already been done.) | ||||
| 
 | ||||
| .sect .data;       begdata:
 | ||||
| .sect .rom;        begrom:
 | ||||
| .sect .bss;        begbss:
 | ||||
| 
 | ||||
| ! Some magic data. All EM systems need these. | ||||
| 
 | ||||
| .define _errno
 | ||||
|  | @ -50,7 +57,3 @@ begtext: | |||
| .define .trppc, .ignmask | ||||
| .comm .trppc, 4              ! ptr to user trap handler | ||||
| .comm .ignmask, 4            ! user trap ignore mask  | ||||
| 
 | ||||
| .define .linenumber, .filename | ||||
| .comm .linenumber, 4         ! current linenumber (used for debugging) | ||||
| .comm .filename, 4           ! ptr to current filename (used for debugging) | ||||
|  |  | |||
							
								
								
									
										25
									
								
								plat/linuxppc/build-pkg.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								plat/linuxppc/build-pkg.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| include("plat/build.lua") | ||||
| 
 | ||||
| ackfile { | ||||
| 	name = "boot", | ||||
| 	srcs = { "./boot.s" }, | ||||
| 	vars = { plat = "linuxppc" } | ||||
| } | ||||
| 
 | ||||
| build_plat_libs { | ||||
| 	name = "libs", | ||||
| 	arch = "powerpc", | ||||
| 	plat = "linuxppc", | ||||
| } | ||||
| 
 | ||||
| installable { | ||||
| 	name = "pkg", | ||||
| 	map = { | ||||
| 		"+tools", | ||||
| 		"+libs", | ||||
| 		"./include+pkg", | ||||
| 		["$(PLATIND)/linuxppc/boot.o"] = "+boot", | ||||
|         ["$(PLATIND)/linuxppc/libsys.a"] = "./libsys+lib", | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										21
									
								
								plat/linuxppc/build-tools.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								plat/linuxppc/build-tools.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| include("plat/build.lua") | ||||
| 
 | ||||
| build_as { | ||||
| 	name = "as", | ||||
| 	arch = "powerpc", | ||||
| } | ||||
| 
 | ||||
| build_ncg { | ||||
| 	name = "ncg", | ||||
| 	arch = "powerpc", | ||||
| } | ||||
| 
 | ||||
| return installable { | ||||
| 	name = "tools", | ||||
| 	map = { | ||||
| 		["$(PLATDEP)/linuxppc/as"] = "+as", | ||||
| 		["$(PLATDEP)/linuxppc/ncg"] = "+ncg", | ||||
| 		["$(PLATIND)/descr/linuxppc"] = "./descr", | ||||
| 		"util/opt+pkg", | ||||
| 	} | ||||
| } | ||||
|  | @ -1,6 +1,4 @@ | |||
| # $Source: /cvsroot/tack/Ack/plat/linux386/descr,v $ | ||||
| # $State: Exp $ | ||||
| # $Revision: 1.1 $ | ||||
| # plat/linuxppc/descr | ||||
| 
 | ||||
| var w=4 | ||||
| var wa=4 | ||||
|  | @ -19,8 +17,8 @@ var xa={x} | |||
| var ARCH=powerpc | ||||
| var PLATFORM=linuxppc | ||||
| var PLATFORMDIR={EM}/share/ack/{PLATFORM} | ||||
| var CPP_F=-D__unix -D__POWERPC | ||||
| var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x80000054 | ||||
| var CPP_F=-D__unix | ||||
| var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x10000054 | ||||
| var C_LIB={PLATFORMDIR}/libc-ansi.a | ||||
| # bitfields reversed for compatibility with (g)cc. | ||||
| var CC_ALIGN=-Vr | ||||
|  | @ -35,25 +33,26 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi | |||
| name be | ||||
| 	from .m.g | ||||
| 	to .s | ||||
| 	program {EM}/lib/ack/{ARCH}/ncg | ||||
| 	program {EM}/lib/ack/{PLATFORM}/ncg | ||||
| 	mapflag -gdb GF=-gdb | ||||
| 	args {GF?} < | ||||
| 	stdout | ||||
| 	need .e | ||||
| end | ||||
| name asopt | ||||
| 	from .s | ||||
| 	to .so | ||||
| 	program {EM}/lib/ack/{ARCH}/top | ||||
| 	args | ||||
| 	optimizer | ||||
| 	stdin | ||||
| 	stdout | ||||
| end | ||||
| # FIXME(dtrg): not working yet | ||||
| #name asopt | ||||
| #	from .s | ||||
| #	to .so | ||||
| #	program {EM}/lib/ack/{PLATFORM}/top | ||||
| #	args | ||||
| #	optimizer | ||||
| #	stdin | ||||
| #	stdout | ||||
| #end | ||||
| name as | ||||
| 	from .s.so | ||||
| 	to .o | ||||
| 	program {EM}/lib/ack/{ARCH}/as | ||||
| 	program {EM}/lib/ack/{PLATFORM}/as | ||||
| 	args - -o > < | ||||
| 	prep cond | ||||
| end | ||||
|  | @ -64,8 +63,9 @@ name led | |||
| 	mapflag -l* LNAME={PLATFORMDIR}/lib* | ||||
| 	mapflag -fp FLOATS={EM}/{LIB}fp | ||||
| 	args {ALIGN} {SEPID?} \ | ||||
| 	    {PLATFORMDIR}/boot.o \ | ||||
| 		({RTS}:.ocm.b.c={PLATFORMDIR}/c-ansi.o) \ | ||||
| 	    (.e:{HEAD}={PLATFORMDIR}/boot.o) \ | ||||
| 		({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \ | ||||
| 		({RTS}:.c={PLATFORMDIR}/c-ansi.o) \ | ||||
| 		({RTS}:.mod={PLATFORMDIR}/modula2.o) \ | ||||
| 		({RTS}:.p={PLATFORMDIR}/pascal.o) \ | ||||
| 		-o > < \ | ||||
|  | @ -74,10 +74,10 @@ name led | |||
| 		(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \ | ||||
| 		(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \ | ||||
| 		(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \ | ||||
| 		{PLATFORMDIR}/liblinux.a \ | ||||
| 		{PLATFORMDIR}/libem.a \ | ||||
| 		{FLOATS?} \ | ||||
| 		(.e:{TAIL}={PLATFORMDIR}/libem.a \ | ||||
| 		           {PLATFORMDIR}/libsys.a \ | ||||
| 		{PLATFORMDIR}/libend.a | ||||
| 		           {PLATFORMDIR}/libend.a) | ||||
| 	linker | ||||
| end | ||||
| name cv | ||||
|  |  | |||
							
								
								
									
										24
									
								
								plat/linuxppc/include/build.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								plat/linuxppc/include/build.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| include("plat/build.lua") | ||||
| 
 | ||||
| headermap = {} | ||||
| packagemap = {} | ||||
| 
 | ||||
| local function addheader(h) | ||||
| 	headermap[h] = "./"..h | ||||
| 	packagemap["$(PLATIND)/linuxppc/include/"..h] = "./"..h | ||||
| end | ||||
| 
 | ||||
| addheader("ack/config.h") | ||||
| addheader("sys/ioctl.h") | ||||
| addheader("unistd.h") | ||||
| 
 | ||||
| acklibrary { | ||||
| 	name = "headers", | ||||
| 	hdrs = headermap | ||||
| } | ||||
| 
 | ||||
| installable { | ||||
| 	name = "pkg", | ||||
| 	map = packagemap | ||||
| } | ||||
| 
 | ||||
|  | @ -42,8 +42,7 @@ __syscall: | |||
| 	bc IFTRUE, GT, 2f | ||||
| 	 | ||||
| 3: | ||||
| 	addis r4, r0, <_errno | ||||
| 	ori r4, r4, >_errno | ||||
| 	li32 r4, _errno | ||||
| 	stw r3, 0(r4) | ||||
| 	addi r3, r0, -1 | ||||
| 	bclr ALWAYS, 0, 0 | ||||
|  |  | |||
							
								
								
									
										16
									
								
								plat/linuxppc/libsys/build.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								plat/linuxppc/libsys/build.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| acklibrary { | ||||
|     name = "lib", | ||||
|     srcs = { | ||||
|         "./*.s", | ||||
|         "plat/linux/libsys/*.c", | ||||
|         "plat/linux/libsys/*.s", | ||||
|     }, | ||||
| 	deps = { | ||||
| 		"lang/cem/libcc.ansi/headers+headers", | ||||
| 		"plat/linuxppc/include+headers", | ||||
| 	}, | ||||
|     vars = { | ||||
|         plat = "linuxppc" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -65,15 +65,13 @@ EUNIMPL = 63		! unimplemented em-instruction called | |||
| 	 | ||||
| 	addi r4, r0, 1 | ||||
| 	rlwnm r4, r4, r3, 0, 31  ! calculate trap bit | ||||
| 	addis r5, r0, <.ignmask | ||||
| 	ori r5, r5, >.ignmask | ||||
| 	li32 r5, .ignmask | ||||
| 	lwz r5, 0(r5)            ! load ignore mask | ||||
| 	and. r4, r4, r5          ! compare | ||||
| 	bclr IFFALSE, EQ, 0      ! return if non-zero | ||||
| 	 | ||||
| 1: | ||||
| 	addis r4, r0, <.trppc | ||||
| 	ori r4, r4, >.trppc | ||||
| 	li32 r4, .trppc | ||||
| 	lwz r5, 0(r4)            ! load user trap routine | ||||
| 	or. r5, r5, r5           ! test | ||||
| 	bc IFTRUE, EQ, fatal     ! if no user trap routine, bail out | ||||
|  | @ -94,8 +92,7 @@ EUNIMPL = 63		! unimplemented em-instruction called | |||
| 
 | ||||
| fatal: | ||||
| 	addi r3, r0, 1 | ||||
| 	addis r4, r0, <message | ||||
| 	ori r4, r4, >message | ||||
| 	li32 r4, message | ||||
| 	addi r5, r0, 6 | ||||
| 	addi r0, r0, 4           ! write() | ||||
| 	sc 0 | ||||
|  |  | |||
|  | @ -140,9 +140,6 @@ showrelo() | |||
| 	case RELOPPC: | ||||
| 		printf("\tPowerPC 26-bit address\n"); | ||||
| 		break; | ||||
| 	case RELOH2: | ||||
| 		printf("\ttop 2 bytes of a 4 byte word\n"); | ||||
| 		break; | ||||
| 	case RELOVC4: | ||||
| 		printf("\tVideoCore IV address in 32-bit instruction\n"); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -158,12 +158,11 @@ struct outrelo { | |||
| /* | ||||
|  * relocation type bits | ||||
|  */ | ||||
| #define RELSZ	0x0fffi     /* relocation length */ | ||||
| #define RELSZ	0x0fff      /* relocation length */ | ||||
| #define RELO1	0x01		/* 1 byte */ | ||||
| #define RELO2	0x02		/* 2 bytes */ | ||||
| #define RELO4	0x03		/* 4 bytes */ | ||||
| #define RELOPPC	0x04		/* 26-bit PowerPC address */ | ||||
| #define RELOH2  0x05        /* write top 2 bytes of 4 byte word */ | ||||
| #define RELOVC4 0x06        /* VideoCore IV address in 32-bit insruction */ | ||||
| #define RELPC	0x2000		/* pc relative */ | ||||
| #define RELBR	0x4000		/* High order byte lowest address. */ | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ static char rcsid[] = "$Id$"; | |||
| 
 | ||||
| #define UBYTE(x)	((x) & BYTEMASK) | ||||
| 
 | ||||
| static long read2(char* addr, int type) | ||||
| static uint16_t read2(char* addr, int type) | ||||
| { | ||||
| 	unsigned short word0, word1; | ||||
| 
 | ||||
|  | @ -28,7 +28,7 @@ static long read2(char* addr, int type) | |||
| 		return (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]); | ||||
| } | ||||
| 
 | ||||
| static long read4(char* addr, int type) | ||||
| static uint32_t read4(char* addr, int type) | ||||
| { | ||||
| 	unsigned short word0, word1; | ||||
| 
 | ||||
|  | @ -49,7 +49,7 @@ static long read4(char* addr, int type) | |||
|  * one of several different ways (depending on what the instruction is). | ||||
|  */ | ||||
| 
 | ||||
| static long get_vc4_valu(char* addr) | ||||
| static uint32_t get_vc4_valu(char* addr) | ||||
| { | ||||
| 	uint16_t opcode = read2(addr, 0); | ||||
| 
 | ||||
|  | @ -104,11 +104,36 @@ static long get_vc4_valu(char* addr) | |||
| 	assert(0 && "unrecognised VC4 instruction"); | ||||
| } | ||||
| 
 | ||||
| /* PowerPC fixups are complex as we need to patch up to the next two
 | ||||
|  * instructions in one of several different ways, depending on what the | ||||
|  * instructions area. | ||||
|  */ | ||||
| 
 | ||||
| static uint32_t get_powerpc_valu(char* addr, uint16_t type) | ||||
| { | ||||
| 	uint32_t opcode1 = read4(addr+0, type); | ||||
| 	uint32_t opcode2 = read4(addr+4, type); | ||||
| 
 | ||||
| 	if ((opcode1 & 0xfc000000) == 0x48000000) | ||||
| 	{ | ||||
| 		/* branch instruction */ | ||||
| 		return opcode1 & 0x03fffffd; | ||||
| 	} | ||||
| 	else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && | ||||
| 	         ((opcode2 & 0xfc000000) == 0x60000000)) | ||||
| 	{ | ||||
| 		/* addis / ori instruction pair */ | ||||
| 		return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff); | ||||
| 	} | ||||
| 
 | ||||
| 	assert(0 && "unrecognised PowerPC instruction"); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * The bits in type indicate how many bytes the value occupies and what | ||||
|  * significance should be attributed to each byte. | ||||
|  */ | ||||
| static long getvalu(char* addr, uint16_t type) | ||||
| static uint32_t getvalu(char* addr, uint16_t type) | ||||
| { | ||||
| 	switch (type & RELSZ) { | ||||
| 	case RELO1: | ||||
|  | @ -118,9 +143,7 @@ static long getvalu(char* addr, uint16_t type) | |||
| 	case RELO4: | ||||
| 		return read4(addr, type); | ||||
| 	case RELOPPC: | ||||
| 		return read4(addr, type) & 0x03FFFFFD; | ||||
| 	case RELOH2: | ||||
| 		return read2(addr, type) << 16; | ||||
| 		return get_powerpc_valu(addr, type); | ||||
| 	case RELOVC4: | ||||
| 		return get_vc4_valu(addr); | ||||
| 	default: | ||||
|  | @ -129,7 +152,7 @@ static long getvalu(char* addr, uint16_t type) | |||
| 	/* NOTREACHED */ | ||||
| } | ||||
| 
 | ||||
| static void write2(long valu, char* addr, int type) | ||||
| static void write2(uint16_t valu, char* addr, int type) | ||||
| { | ||||
| 	unsigned short	word0, word1; | ||||
| 
 | ||||
|  | @ -142,7 +165,7 @@ static void write2(long valu, char* addr, int type) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void write4(long valu, char* addr, int type) | ||||
| static void write4(uint32_t valu, char* addr, int type) | ||||
| { | ||||
| 	unsigned short	word0, word1; | ||||
| 
 | ||||
|  | @ -170,7 +193,7 @@ static void write4(long valu, char* addr, int type) | |||
|  * one of several different ways (depending on what the instruction is). | ||||
|  */ | ||||
| 
 | ||||
| static void put_vc4_valu(char* addr, long value) | ||||
| static void put_vc4_valu(char* addr, uint32_t value) | ||||
| { | ||||
| 	uint16_t opcode = read2(addr, 0); | ||||
| 
 | ||||
|  | @ -220,12 +243,42 @@ static void put_vc4_valu(char* addr, long value) | |||
| 		assert(0 && "unrecognised VC4 instruction"); | ||||
| } | ||||
| 
 | ||||
| /* PowerPC fixups are complex as we need to patch up to the next two
 | ||||
|  * instructions in one of several different ways, depending on what the | ||||
|  * instructions area. | ||||
|  */ | ||||
| 
 | ||||
| static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type) | ||||
| { | ||||
| 	uint32_t opcode1 = read4(addr+0, type); | ||||
| 	uint32_t opcode2 = read4(addr+4, type); | ||||
| 
 | ||||
| 	if ((opcode1 & 0xfc000000) == 0x48000000) | ||||
| 	{ | ||||
| 		/* branch instruction */ | ||||
| 		uint32_t i = opcode1 & ~0x03fffffd; | ||||
| 		i |= value & 0x03fffffd; | ||||
| 		write4(i, addr, type); | ||||
| 	} | ||||
| 	else if (((opcode1 & 0xfc1f0000) == 0x3c000000) && | ||||
| 	         ((opcode2 & 0xfc000000) == 0x60000000)) | ||||
| 	{ | ||||
| 		uint16_t hi = value >> 16; | ||||
| 		uint16_t lo = value & 0xffff; | ||||
| 
 | ||||
| 		write4((opcode1 & 0xffff0000) | hi, addr+0, type); | ||||
| 		write4((opcode2 & 0xffff0000) | lo, addr+4, type); | ||||
| 	} | ||||
| 	else | ||||
| 		assert(0 && "unrecognised PowerPC instruction"); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * The bits in type indicate how many bytes the value occupies and what | ||||
|  * significance should be attributed to each byte. | ||||
|  * We do not check for overflow. | ||||
|  */ | ||||
| static putvalu(long valu, char* addr, uint16_t type) | ||||
| static putvalu(uint32_t valu, char* addr, uint16_t type) | ||||
| { | ||||
| 
 | ||||
| 	switch (type & RELSZ) { | ||||
|  | @ -239,14 +292,7 @@ static putvalu(long valu, char* addr, uint16_t type) | |||
| 		write4(valu, addr, type); | ||||
| 		break; | ||||
| 	case RELOPPC: | ||||
| 	{ | ||||
| 		long i = read4(addr, type) & ~0x03FFFFFD; | ||||
| 		i |= valu & 0x03FFFFFD; | ||||
| 		write4(i, addr, type); | ||||
| 		break; | ||||
| 	} | ||||
| 	case RELOH2: | ||||
| 		write2(valu>>16, addr, type); | ||||
| 		put_powerpc_valu(addr, valu, type); | ||||
| 		break; | ||||
| 	case RELOVC4: | ||||
| 		put_vc4_valu(addr, valu); | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
| #define BORS(x,y) y | ||||
| #endif | ||||
| 
 | ||||
| #define MAXREGS BORS(80,30) | ||||
| #define MAXREGS BORS(200,30) | ||||
| #define MAXPROPS BORS(120,20) | ||||
| #define MAXTOKENS BORS(100,60) | ||||
| #define MAXATT 6 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue