summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKathy Gray2014-11-12 14:45:49 +0000
committerKathy Gray2014-11-12 14:45:49 +0000
commitfa1fca03d9e62d01587166506cccba7895f3a2b0 (patch)
treef7f849758b55121823c234f22559c57452d03a64 /src
parentb24b4f40cb7c907ac3c93c6036703ab708e164c0 (diff)
Stop overzealously looking for constructors, only when the type suggests to
Diffstat (limited to 'src')
-rw-r--r--src/test/power.sail78
-rw-r--r--src/type_check.ml16
-rw-r--r--src/type_internal.mli2
3 files changed, 88 insertions, 8 deletions
diff --git a/src/test/power.sail b/src/test/power.sail
index 4305c099..5f4783ce 100644
--- a/src/test/power.sail
+++ b/src/test/power.sail
@@ -427,6 +427,20 @@ function clause execute (Bclr (BO, BI, BH, LK)) =
if LK then LR := CIA + 4 else ()
}
+union ast member (bit[7]) Sc
+
+function clause decode (0b010001 :
+(bit[5]) _ :
+(bit[5]) _ :
+(bit[4]) _ :
+(bit[7]) LEV :
+(bit[3]) _ :
+0b1 :
+(bit[1]) _ as instr) =
+ Sc (LEV)
+
+function clause execute (Sc (LEV)) = ()
+
union ast member (bit[5], bit[5], bit[16]) Lwz
function clause decode (0b100000 :
@@ -538,9 +552,9 @@ function clause execute (Lswi (RT, RA, NB)) =
{
(bit[64]) EA := 0;
if RA == 0 then EA := 0 else EA := GPR[RA];
- (range<0, 32> ) r := 0;
+ ([|32|]) r := 0;
r := RT - 1;
- (range<0, 32> ) size := if NB == 0 then 32 else NB;
+ ([|32|]) size := if NB == 0 then 32 else NB;
(bit[256]) membuffer := MEMr (EA,size);
j := 0;
i := 32;
@@ -548,7 +562,7 @@ function clause execute (Lswi (RT, RA, NB)) =
{
if i == 32
then {
- r := (range<0, 32> ) (r + 1) mod 32;
+ r := ([|32|]) (r + 1) mod 32;
GPR[r] := 0
}
else ();
@@ -584,6 +598,24 @@ function clause execute (Addis (RT, RA, SI)) =
then GPR[RT] := EXTS (SI : 0b0000000000000000)
else GPR[RT] := GPR[RA] + EXTS (SI : 0b0000000000000000)
+union ast member (bit[5], bit[5], bit[5], bit, bit) Add
+
+function clause decode (0b011111 :
+(bit[5]) RT :
+(bit[5]) RA :
+(bit[5]) RB :
+[OE] :
+0b100001010 :
+[Rc] as instr) =
+ Add (RT,RA,RB,OE,Rc)
+
+function clause execute (Add (RT, RA, RB, OE, Rc)) =
+ {
+ temp := GPR[RA] + GPR[RB];
+ GPR[RT] := temp;
+ if Rc then set_overflow_cr0 (temp) else ()
+ }
+
union ast member (bit[5], bit[5], bit[5], bit, bit) Subf
function clause decode (0b011111 :
@@ -602,6 +634,26 @@ function clause execute (Subf (RT, RA, RB, OE, Rc)) =
if Rc then set_overflow_cr0 (temp) else ()
}
+union ast member (bit[5], bit[5], bit[16]) Addic
+
+function clause decode (0b001100 :
+(bit[5]) RT :
+(bit[5]) RA :
+(bit[16]) SI as instr) =
+ Addic (RT,RA,SI)
+
+function clause execute (Addic (RT, RA, SI)) = GPR[RT] := GPR[RA] + EXTS (SI)
+
+union ast member (bit[5], bit[5], bit[16]) Addic
+
+function clause decode (0b001101 :
+(bit[5]) RT :
+(bit[5]) RA :
+(bit[16]) SI as instr) =
+ Addic (RT,RA,SI)
+
+function clause execute (Addic (RT, RA, SI)) = GPR[RT] := GPR[RA] + EXTS (SI)
+
union ast member (bit[5], bit[5], bit, bit) Neg
function clause decode (0b011111 :
@@ -638,6 +690,26 @@ function clause execute (Mullw (RT, RA, RB, OE, Rc)) =
if Rc then set_overflow_cr0 (temp) else ()
}
+union ast member (bit[3], bit, bit[5], bit[16]) Cmpi
+
+function clause decode (0b001011 :
+(bit[3]) BF :
+(bit[1]) _ :
+[L] :
+(bit[5]) RA :
+(bit[16]) SI as instr) =
+ Cmpi (BF,L,RA,SI)
+
+function clause execute (Cmpi (BF, L, RA, SI)) =
+ {
+ (bit[64]) a := 0;
+ if L == 0 then a := EXTS ((GPR[RA])[32 .. 63]) else a := GPR[RA];
+ if a < EXTS (SI)
+ then c := 0b100
+ else if a > EXTS (SI) then c := 0b010 else c := 0b001;
+ CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO]
+ }
+
union ast member (bit[3], bit, bit[5], bit[5]) Cmp
function clause decode (0b011111 :
diff --git a/src/type_check.ml b/src/type_check.ml
index bfb59b3f..884e90c6 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -237,18 +237,24 @@ let rec check_pattern envs emp_tag expect_t (P_aux(p,(l,annot))) : ((tannot pat)
(P_aux(P_typ(typ,pat'),(l,Base(([],t),Emp_local,[],pure_e))),env,cs@constraints,t)
| P_id id ->
let i = id_to_string id in
+ let default = let tannot = Base(([],expect_t),emp_tag,cs,pure_e) in
+ (P_aux(p,(l,tannot)),Envmap.from_list [(i,tannot)],cs,expect_t) in
(match Envmap.apply t_env i with
| Some(Base((params,t),Constructor,cs,ef)) ->
let t,cs,ef = subst params t cs ef in
(match t.t with
| Tfn({t = Tid "unit"},t',IP_none,ef) ->
- let tp,cp = type_consistent (Expr l) d_env t' expect_t in
- (P_aux(P_app(id,[]),(l,(Base(([],t),Constructor,[],pure_e)))),Envmap.empty,cs@cp,tp)
+ if conforms_to_t d_env false false t' expect_t
+ then
+ let tp,cp = type_consistent (Expr l) d_env t' expect_t in
+ (P_aux(P_app(id,[]),(l,(Base(([],t),Constructor,[],pure_e)))),Envmap.empty,cs@cp,tp)
+ else default
| Tfn(t1,t',IP_none,e) ->
- typ_error l ("Constructor " ^ i ^ " expects arguments of type " ^ (t_to_string t) ^ ", found none")
+ if conforms_to_t d_env false false t' expect_t
+ then typ_error l ("Constructor " ^ i ^ " expects arguments of type " ^ (t_to_string t) ^ ", found none")
+ else default
| _ -> raise (Reporting_basic.err_unreachable l "Constructor tannot does not have function type"))
- | _ -> let tannot = Base(([],expect_t),emp_tag,cs,pure_e) in
- (P_aux(p,(l,tannot)),Envmap.from_list [(id_to_string id,tannot)],cs,expect_t))
+ | _ -> default)
| P_app(id,pats) ->
let i = id_to_string id in
(match Envmap.apply t_env i with
diff --git a/src/type_internal.mli b/src/type_internal.mli
index 63a18106..90eaea91 100644
--- a/src/type_internal.mli
+++ b/src/type_internal.mli
@@ -171,6 +171,8 @@ val check_tannot : Parse_ast.l -> tannot -> nexp_range list -> effect -> tannot
val nexp_eq : nexp -> nexp -> bool
+val conforms_to_t : def_envs -> bool -> bool -> t -> t -> bool
+
(* type_consistent is similar to a standard type equality, except in the case of [[consistent t1 t2]] where
t1 and t2 are both enum types and t1 is contained within the range of t2: i.e.
enum 2 5 is consistent with enum 0 10, but not vice versa.