| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | ! Copyright (C) 2010 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2014-12-13 19:10:21 -05:00
										 |  |  | USING: accessors combinators combinators.short-circuit | 
					
						
							|  |  |  | compiler.cfg.hats compiler.cfg.instructions | 
					
						
							|  |  |  | compiler.cfg.utilities compiler.cfg.value-numbering.graph | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  | compiler.cfg.value-numbering.math | 
					
						
							| 
									
										
										
										
											2014-12-13 19:10:21 -05:00
										 |  |  | compiler.cfg.value-numbering.rewrite cpu.architecture fry kernel | 
					
						
							|  |  |  | make math sequences ;
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | IN: compiler.cfg.value-numbering.alien | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  | M: ##box-displaced-alien rewrite | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     dup displacement>> vreg>insn zero-insn? | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  |     [ [ dst>> ] [ base>> ] bi <copy> ] [ drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | ! ##box-displaced-alien f 1 2 3 <class> | 
					
						
							|  |  |  | ! ##unbox-c-ptr 4 1 <class> | 
					
						
							|  |  |  | ! => | 
					
						
							|  |  |  | ! ##box-displaced-alien f 1 2 3 <class> | 
					
						
							|  |  |  | ! ##unbox-c-ptr 5 3 <class> | 
					
						
							|  |  |  | ! ##add 4 5 2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  | : rewrite-unbox-alien ( insn box-insn -- insn )
 | 
					
						
							|  |  |  |     [ dst>> ] [ src>> ] bi* <copy> ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  | : rewrite-unbox-displaced-alien ( insn box-insn -- insns )
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ dst>> ] | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |         [ [ base>> ] [ base-class>> ] [ displacement>> ] tri ] bi*
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  |         [ ^^unbox-c-ptr ] dip
 | 
					
						
							| 
									
										
										
										
											2011-11-11 22:48:38 -05:00
										 |  |  |         ##add, | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  |     ] { } make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  | : rewrite-unbox-any-c-ptr ( insn -- insn/f )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     dup src>> vreg>insn | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |         { [ dup ##box-alien? ] [ rewrite-unbox-alien ] } | 
					
						
							|  |  |  |         { [ dup ##box-displaced-alien? ] [ rewrite-unbox-displaced-alien ] } | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  |         [ 2drop f ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##unbox-any-c-ptr rewrite rewrite-unbox-any-c-ptr ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##unbox-alien rewrite rewrite-unbox-any-c-ptr ;
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | ! Fuse ##add-imm into ##load-memory(-imm) and ##store-memory(-imm) | 
					
						
							|  |  |  | ! just update the offset in the instruction | 
					
						
							|  |  |  | : fuse-base-offset? ( insn -- ? )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     base>> vreg>insn ##add-imm? ;
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | : fuse-base-offset ( insn -- insn' )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     dup base>> vreg>insn | 
					
						
							|  |  |  |     [ src1>> ] [ src2>> ] bi
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  |     [ >>base ] [ '[ _ + ] change-offset ] bi* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Fuse ##add-imm into ##load-memory and ##store-memory | 
					
						
							|  |  |  | ! just update the offset in the instruction | 
					
						
							|  |  |  | : fuse-displacement-offset? ( insn -- ? )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     { [ scale>> 0 = ] [ displacement>> vreg>insn ##add-imm? ] } 1&& ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fuse-displacement-offset ( insn -- insn' )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     dup displacement>> vreg>insn | 
					
						
							|  |  |  |     [ src1>> ] [ src2>> ] bi
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  |     [ >>displacement ] [ '[ _ + ] change-offset ] bi* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Fuse ##add into ##load-memory-imm and ##store-memory-imm | 
					
						
							|  |  |  | ! construct a new ##load-memory or ##store-memory with the | 
					
						
							|  |  |  | ! ##add's operand as the displacement | 
					
						
							|  |  |  | : fuse-displacement? ( insn -- ? )
 | 
					
						
							| 
									
										
										
										
											2010-05-04 06:46:21 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         [ offset>> 0 = complex-addressing? or ] | 
					
						
							|  |  |  |         [ base>> vreg>insn ##add? ] | 
					
						
							|  |  |  |     } 1&& ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | GENERIC: alien-insn-value ( insn -- value )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##load-memory-imm alien-insn-value dst>> ;
 | 
					
						
							|  |  |  | M: ##store-memory-imm alien-insn-value src>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: new-alien-insn ( value base displacement scale offset rep c-type insn -- insn )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 01:04:26 -05:00
										 |  |  | M: ##load-memory-imm new-alien-insn drop ##load-memory new-insn ;
 | 
					
						
							|  |  |  | M: ##store-memory-imm new-alien-insn drop ##store-memory new-insn ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fuse-displacement ( insn -- insn' )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [ alien-insn-value ] | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |         [ base>> vreg>insn [ src1>> ] [ src2>> ] bi ] | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  |         [ drop 0 ] | 
					
						
							|  |  |  |         [ offset>> ] | 
					
						
							|  |  |  |         [ rep>> ] | 
					
						
							|  |  |  |         [ c-type>> ] | 
					
						
							|  |  |  |         [ ] | 
					
						
							|  |  |  |     } cleave new-alien-insn ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Fuse ##shl-imm into ##load-memory or ##store-memory | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  | : scale-insn? ( insn -- ? )
 | 
					
						
							|  |  |  |     { [ ##shl-imm? ] [ src2>> { 1 2 3 } member? ] } 1&& ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fuse-scale? ( insn -- ? )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     { [ scale>> 0 = ] [ displacement>> vreg>insn scale-insn? ] } 1&& ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : fuse-scale ( insn -- insn' )
 | 
					
						
							| 
									
										
										
										
											2010-04-24 06:06:16 -04:00
										 |  |  |     dup displacement>> vreg>insn | 
					
						
							|  |  |  |     [ src1>> ] [ src2>> ] bi
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  |     [ >>displacement ] [ >>scale ] bi* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : rewrite-memory-op ( insn -- insn/f )
 | 
					
						
							| 
									
										
										
										
											2010-05-04 06:46:21 -04:00
										 |  |  |     complex-addressing? [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             { [ dup fuse-base-offset? ] [ fuse-base-offset ] } | 
					
						
							|  |  |  |             { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] } | 
					
						
							|  |  |  |             { [ dup fuse-scale? ] [ fuse-scale ] } | 
					
						
							|  |  |  |             [ drop f ] | 
					
						
							|  |  |  |         } cond
 | 
					
						
							|  |  |  |     ] [ drop f ] if ;
 | 
					
						
							| 
									
										
										
										
											2010-04-24 00:13:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : rewrite-memory-imm-op ( insn -- insn/f )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ dup fuse-base-offset? ] [ fuse-base-offset ] } | 
					
						
							|  |  |  |         { [ dup fuse-displacement? ] [ fuse-displacement ] } | 
					
						
							|  |  |  |         [ drop f ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##load-memory rewrite rewrite-memory-op ;
 | 
					
						
							|  |  |  | M: ##load-memory-imm rewrite rewrite-memory-imm-op ;
 | 
					
						
							|  |  |  | M: ##store-memory rewrite rewrite-memory-op ;
 | 
					
						
							|  |  |  | M: ##store-memory-imm rewrite rewrite-memory-imm-op ;
 |