Răsfoiți Sursa

[hl] added OAsm

Nicolas Cannasse 1 an în urmă
părinte
comite
5ddfcc84f7

+ 22 - 0
src/generators/genhl.ml

@@ -2086,6 +2086,28 @@ and eval_expr ctx e =
 			let r = alloc_tmp ctx (to_type ctx e.etype) in
             op ctx (OUnsafeCast (r, eval_expr ctx value));
 			r
+		| "$asm", [mode; value] ->
+			let mode = (match get_const mode with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant mode required" e.epos
+			) in
+			let value = (match get_const value with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant value required" e.epos
+			) in
+			op ctx (OAsm (mode, value, 0));
+			alloc_tmp ctx HVoid
+		| "$asm", [mode; value; reg] ->
+			let mode = (match get_const mode with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant mode required" e.epos
+			) in
+			let value = (match get_const value with
+				| TInt m -> Int32.to_int m
+				| _ -> abort "Constant value required" e.epos
+			) in
+			op ctx (OAsm (mode, value, (eval_expr ctx reg) + 1));
+			alloc_tmp ctx HVoid
 		| _ ->
 			abort ("Unknown native call " ^ s) e.epos)
 	| TEnumIndex v ->

+ 2 - 0
src/generators/hl2c.ml

@@ -1110,6 +1110,8 @@ let generate_function ctx f =
 				Globals.die "" __LOC__
 			)) in
 			sexpr "__hl_prefetch_m%d(%s)" mode expr
+		| OAsm _ ->
+			sexpr "UNSUPPORTED ASM OPCODE";
 	) f.code;
 	flush_options (Array.length f.code);
 	unblock();

+ 13 - 0
src/generators/hlcode.ml

@@ -202,6 +202,7 @@ type opcode =
 	| ORefOffset of reg * reg * reg
 	| ONop of string
 	| OPrefetch of reg * field index * int
+    | OAsm of int * int * reg
 
 type fundecl = {
 	fpath : string * string;
@@ -574,6 +575,18 @@ let ostr fstr o =
 	| ORefOffset (r,r2,off) -> Printf.sprintf "refoffset %d, %d, %d" r r2 off
 	| ONop s -> if s = "" then "nop" else "nop " ^ s
 	| OPrefetch (r,f,mode) -> Printf.sprintf "prefetch %d[%d] %d" r f mode
+	| OAsm (mode, value, reg) ->
+		match mode with
+		| 0 when reg = 0 ->
+			Printf.sprintf "asm %.2X" value
+		| 1 when reg = 0 ->
+			Printf.sprintf "asm scratch R%d" value
+		| 2 ->
+			Printf.sprintf "asm R%d := %d" value (reg - 1)
+		| 3 ->
+			Printf.sprintf "asm %d := R%d" (reg - 1) value
+		| _ ->
+			Printf.sprintf "asm[%d] %d%s" mode value (if reg = 0 then "" else ", " ^ string_of_int (reg-1))
 
 let fundecl_name f = if snd f.fpath = "" then "fun$" ^ (string_of_int f.findex) else (fst f.fpath) ^ "." ^ (snd f.fpath)
 

+ 4 - 0
src/generators/hlinterp.ml

@@ -1154,6 +1154,8 @@ let interp ctx f args =
 			(match get r2, get off with
 			| VRef (RArray (a,pos),t), VInt i -> set r (VRef (RArray (a,pos + Int32.to_int i),t))
 			| _ -> Globals.die "" __LOC__)
+		| OAsm _ ->
+			throw_msg ctx "Unsupported ASM"
 		| ONop _ | OPrefetch _ ->
 			()
 		);
@@ -2545,6 +2547,8 @@ let check code macros =
 				();
 			| OPrefetch (r,f,_) ->
 				if f = 0 then ignore(rtype r) else ignore(tfield r (f - 1) false)
+			| OAsm (_,_,r) ->
+				if r > 0 then ignore(rtype (r - 1))
 		) f.code
 		(* TODO : check that all path correctly initialize NULL values and reach a return *)
 	in

+ 11 - 0
src/generators/hlopt.ml

@@ -166,6 +166,12 @@ let opcode_fx frw op =
 		()
 	| OPrefetch (r,_,_) ->
 		read r
+    | OAsm (_,_,r) ->
+        if r > 0 then begin
+            (* assume both *)
+            read (r - 1);
+            write (r - 1);
+        end
 
 let opcode_eq a b =
 	match a, b with
@@ -437,6 +443,11 @@ let opcode_map read write op =
 	| OPrefetch (r, fid, mode) ->
 		let r2 = read r in
 		OPrefetch (r2, fid, mode)
+	| OAsm (_, _, 0) ->
+		op
+	| OAsm (mode, value, r) ->
+		let r2 = read (r - 1) in
+		OAsm (mode, value, (write r2) + 1)
 
 (* build code graph *)