Bläddra i källkod

fixed HL NaN handling, added OJNotLt, OJNotGte

Nicolas Cannasse 8 år sedan
förälder
incheckning
34ce77fb4e

+ 2 - 2
src/generators/genhl.ml

@@ -1319,8 +1319,8 @@ and jump_expr ctx e jcond =
 		free ctx r1;
 		let unsigned = unsigned_op e1 e2 in
 		jump ctx (fun i ->
-			let lt a b = if unsigned then OJULt (a,b,i) else OJSLt (a,b,i) in
-			let gte a b = if unsigned then OJUGte (a,b,i) else OJSGte (a,b,i) in
+			let lt a b = if unsigned then OJULt (a,b,i) else if not jcond && is_float t then OJNotGte (b,a,i) else OJSLt (a,b,i) in
+			let gte a b = if unsigned then OJUGte (a,b,i) else if not jcond && is_float t then OJNotLt (b,a,i) else OJSGte (a,b,i) in
 			match jop with
 			| OpEq -> if jcond then OJEq (r1,r2,i) else OJNotEq (r1,r2,i)
 			| OpNotEq -> if jcond then OJNotEq (r1,r2,i) else OJEq (r1,r2,i)

+ 4 - 0
src/generators/hl2c.ml

@@ -797,6 +797,10 @@ let generate_function ctx f =
 			sexpr "if( ((unsigned)%s) < ((unsigned)%s) ) goto %s" (reg a) (reg b) (label d)
 		| OJUGte (a,b,d) ->
 			sexpr "if( ((unsigned)%s) >= ((unsigned)%s) ) goto %s" (reg a) (reg b) (label d)
+		| OJNotLt (a,b,d) ->
+			sexpr "if( !(%s < %s) ) goto %s" (reg a) (reg b) (label d)
+		| OJNotGte (a,b,d) ->
+			sexpr "if( !(%s >= %s) ) goto %s" (reg a) (reg b) (label d)
 		| OJEq (a,b,d) ->
 			compare_op CEq a b d
 		| OJNotEq (a,b,d) ->

+ 4 - 0
src/generators/hlcode.ml

@@ -146,6 +146,8 @@ type opcode =
 	| OJSLte of reg * reg * int
 	| OJULt of reg * reg * int
 	| OJUGte of reg * reg * int
+	| OJNotLt of reg * reg * int
+	| OJNotGte of reg * reg * int
 	| OJEq of reg * reg * int
 	| OJNotEq of reg * reg * int
 	| OJAlways of int
@@ -511,6 +513,8 @@ let ostr fstr o =
 	| OJSLte (r,a,b) -> Printf.sprintf "jslte %d,%d,%d" r a b
 	| OJULt (a,b,i) -> Printf.sprintf "jult %d,%d,%d" a b i
 	| OJUGte (a,b,i) -> Printf.sprintf "jugte %d,%d,%d" a b i
+	| OJNotLt (a,b,i) -> Printf.sprintf "jnotlt %d,%d,%d" a b i
+	| OJNotGte (a,b,i) -> Printf.sprintf "jnotgte %d,%d,%d" a b i
 	| OJEq (a,b,i) -> Printf.sprintf "jeq %d,%d,%d" a b i
 	| OJNotEq (a,b,i) -> Printf.sprintf "jnoteq %d,%d,%d" a b i
 	| OJAlways d -> Printf.sprintf "jalways %d" d

+ 7 - 3
src/generators/hlinterp.ml

@@ -883,6 +883,8 @@ let interp ctx f args =
 		| OJSLte (a,b,i) -> if vcompare a b (<=) then pos := !pos + i
 		| OJULt (a,b,i) -> if ucompare (get a) (get b) < 0 then pos := !pos + i
 		| OJUGte (a,b,i) -> if ucompare (get a) (get b) >= 0 then pos := !pos + i
+		| OJNotLt (a,b,i) -> if not (vcompare a b (<)) then pos := !pos + i
+		| OJNotGte (a,b,i) -> if not (vcompare a b (>=)) then pos := !pos + i
 		| OJEq (a,b,i) -> if vcompare a b (=) then pos := !pos + i
 		| OJNotEq (a,b,i) -> if not (vcompare a b (=)) then pos := !pos + i
 		| OJAlways i -> pos := !pos + i
@@ -2281,7 +2283,7 @@ let check code macros =
 			| OJNull (r,delta) | OJNotNull (r,delta) ->
 				ignore(rtype r);
 				can_jump delta
-			| OJUGte (a,b,delta) | OJULt (a,b,delta) | OJSGte (a,b,delta) | OJSLt (a,b,delta) | OJSGt (a,b,delta) | OJSLte (a,b,delta) ->
+			| OJUGte (a,b,delta) | OJULt (a,b,delta) | OJSGte (a,b,delta) | OJSLt (a,b,delta) | OJSGt (a,b,delta) | OJSLte (a,b,delta) | OJNotLt (a,b,delta) | OJNotGte (a,b,delta) ->
 				if not (safe_cast (rtype a) (rtype b)) then reg b (rtype a);
 				can_jump delta
 			| OJEq (a,b,delta) | OJNotEq (a,b,delta) ->
@@ -2781,8 +2783,10 @@ let make_spec (code:code) (f:fundecl) =
 			| OJSGte (a,b,_) -> semit (SJComp (">=",args.(a),args.(b)))
 			| OJSGt (a,b,_) -> semit (SJComp (">",args.(a),args.(b)))
 			| OJSLte (a,b,_) -> semit (SJComp ("<=",args.(a),args.(b)))
-			| OJULt (a,b,_) -> semit (SJComp ("<!",args.(a),args.(b)))
-			| OJUGte (a,b,_) -> semit (SJComp (">=!",args.(a),args.(b)))
+			| OJULt (a,b,_) -> semit (SJComp ("<U",args.(a),args.(b)))
+			| OJUGte (a,b,_) -> semit (SJComp (">=U",args.(a),args.(b)))
+			| OJNotLt (a,b,_) -> semit (SJComp ("not<",args.(a),args.(b)))
+			| OJNotGte (a,b,_) -> semit (SJComp ("not>=",args.(a),args.(b)))
 			| OJEq (a,b,_) -> semit (SJComp ("==",args.(a),args.(b)))
 			| OJNotEq (a,b,_) -> semit (SJComp ("!=",args.(a),args.(b)))
 			| OJAlways _ -> semit SJump

+ 9 - 3
src/generators/hlopt.ml

@@ -61,7 +61,7 @@ type control =
 
 let control = function
 	| OJTrue (_,d) | OJFalse (_,d) | OJNull (_,d) | OJNotNull (_,d)
-	| OJSLt (_,_,d) | OJSGte (_,_,d) | OJSGt (_,_,d) | OJSLte (_,_,d) | OJULt (_,_,d) | OJUGte (_,_,d) | OJEq (_,_,d) | OJNotEq (_,_,d) ->
+	| OJSLt (_,_,d) | OJSGte (_,_,d) | OJSGt (_,_,d) | OJSLte (_,_,d) | OJULt (_,_,d) | OJUGte (_,_,d) | OJEq (_,_,d) | OJNotEq (_,_,d) | OJNotLt (_,_,d) | OJNotGte (_,_,d) ->
 		CJCond d
 	| OJAlways d ->
 		CJAlways d
@@ -121,7 +121,7 @@ let opcode_fx frw op =
 		read a
 	| OJTrue (r,_) | OJFalse (r,_) | OJNull (r,_) | OJNotNull (r,_) ->
 		read r
-	| OJSLt (a,b,_) | OJSGte (a,b,_) | OJSGt (a,b,_) | OJSLte (a,b,_) | OJULt (a,b,_) | OJUGte (a,b,_) | OJEq (a,b,_) | OJNotEq (a,b,_) ->
+	| OJSLt (a,b,_) | OJSGte (a,b,_) | OJSGt (a,b,_) | OJSLte (a,b,_) | OJULt (a,b,_) | OJUGte (a,b,_) | OJNotLt (a,b,_) | OJNotGte (a,b,_) | OJEq (a,b,_) | OJNotEq (a,b,_) ->
 		read a; read b;
 	| OJAlways _ | OLabel _ ->
 		()
@@ -304,6 +304,10 @@ let opcode_map read write op =
 		OJULt (read a, read b, d)
 	| OJUGte (a,b,d) ->
 		OJUGte (read a, read b, d)
+	| OJNotLt (a,b,d) ->
+		OJNotLt (read a, read b, d)
+	| OJNotGte (a,b,d) ->
+		OJNotGte (read a, read b, d)
 	| OJEq (a,b,d) ->
 		OJEq (read a, read b, d)
 	| OJNotEq (a,b,d) ->
@@ -776,7 +780,7 @@ let optimize dump (f:fundecl) =
 			| ONop _ -> ()
 			| _ ->
 				(match op with
-				| OJTrue _ | OJFalse _ | OJNull _ | OJNotNull _  | OJSLt _ | OJSGte _ | OJSGt _ | OJSLte _ | OJULt _ | OJUGte _ | OJEq _ | OJNotEq _ | OJAlways _ | OSwitch _  | OTrap _ ->
+				| OJTrue _ | OJFalse _ | OJNull _ | OJNotNull _  | OJSLt _ | OJSGte _ | OJSGt _ | OJSLte _ | OJNotLt _ | OJNotGte _ | OJULt _ | OJUGte _ | OJEq _ | OJNotEq _ | OJAlways _ | OSwitch _  | OTrap _ ->
 					jumps := i :: !jumps
 				| _ -> ());
 				let op = if reg_remap then opcode_map (fun r -> reg_map.(r)) (fun r -> reg_map.(r)) op else op in
@@ -800,6 +804,8 @@ let optimize dump (f:fundecl) =
 			| OJSGt (a,b,d) -> OJSGt (a,b,pos d)
 			| OJULt (a,b,d) -> OJULt (a,b,pos d)
 			| OJUGte (a,b,d) -> OJUGte (a,b,pos d)
+			| OJNotLt (a,b,d) -> OJNotLt (a,b,pos d)
+			| OJNotGte (a,b,d) -> OJNotGte (a,b,pos d)
 			| OJEq (a,b,d) -> OJEq (a,b,pos d)
 			| OJNotEq (a,b,d) -> OJNotEq (a,b,pos d)
 			| OJAlways d -> OJAlways (pos d)