3
3
use crate :: ir:: pcc:: * ;
4
4
use crate :: ir:: types:: * ;
5
5
use crate :: ir:: MemFlags ;
6
+ use crate :: ir:: Type ;
6
7
use crate :: isa:: aarch64:: inst:: args:: { PairAMode , ShiftOp } ;
7
8
use crate :: isa:: aarch64:: inst:: ALUOp ;
8
9
use crate :: isa:: aarch64:: inst:: Inst ;
@@ -11,8 +12,11 @@ use crate::machinst::Reg;
11
12
use crate :: machinst:: VCode ;
12
13
use crate :: trace;
13
14
14
- fn get_fact ( vcode : & VCode < Inst > , reg : Reg ) -> PccResult < & Fact > {
15
- vcode. vreg_fact ( reg. into ( ) ) . ok_or ( PccError :: MissingFact )
15
+ fn get_fact_or_default ( vcode : & VCode < Inst > , reg : Reg ) -> PccResult < & Fact > {
16
+ vcode
17
+ . vreg_fact ( reg. into ( ) )
18
+ . or_else ( || Fact :: infer_from_type ( vcode. vreg_type ( reg. into ( ) ) ) )
19
+ . ok_or ( PccError :: MissingFact )
16
20
}
17
21
18
22
fn has_fact ( vcode : & VCode < Inst > , reg : Reg ) -> bool {
@@ -130,21 +134,19 @@ pub(crate) fn check(ctx: &FactContext, vcode: &VCode<Inst>, inst: &Inst) -> PccR
130
134
rd,
131
135
rn,
132
136
rm,
133
- } if has_fact ( vcode, * rn) && has_fact ( vcode, * rm) => {
134
- check_output ( & ctx, vcode, rd. to_reg ( ) , || {
135
- let rn = get_fact ( vcode, * rn) ?;
136
- let rm = get_fact ( vcode, * rm) ?;
137
- fail_if_missing ( ctx. add ( rn, rm, size. bits ( ) . into ( ) ) )
138
- } )
139
- }
137
+ } => check_output ( & ctx, vcode, rd. to_reg ( ) , || {
138
+ let rn = get_fact_or_default ( vcode, * rn) ?;
139
+ let rm = get_fact_or_default ( vcode, * rm) ?;
140
+ fail_if_missing ( ctx. add ( rn, rm, size. bits ( ) . into ( ) ) )
141
+ } ) ,
140
142
Inst :: AluRRImm12 {
141
143
alu_op : ALUOp :: Add ,
142
144
size,
143
145
rd,
144
146
rn,
145
147
imm12,
146
- } if has_fact ( vcode , * rn ) => check_output ( & ctx, vcode, rd. to_reg ( ) , || {
147
- let rn = get_fact ( vcode, * rn) ?;
148
+ } => check_output ( & ctx, vcode, rd. to_reg ( ) , || {
149
+ let rn = get_fact_or_default ( vcode, * rn) ?;
148
150
let imm_fact = Fact :: ValueMax {
149
151
bit_width : size. bits ( ) . into ( ) ,
150
152
max : imm12. value ( ) ,
@@ -160,8 +162,8 @@ pub(crate) fn check(ctx: &FactContext, vcode: &VCode<Inst>, inst: &Inst) -> PccR
160
162
shiftop,
161
163
} if shiftop. op ( ) == ShiftOp :: LSL && has_fact ( vcode, * rn) && has_fact ( vcode, * rm) => {
162
164
check_output ( & ctx, vcode, rd. to_reg ( ) , || {
163
- let rn = get_fact ( vcode, * rn) ?;
164
- let rm = get_fact ( vcode, * rm) ?;
165
+ let rn = get_fact_or_default ( vcode, * rn) ?;
166
+ let rm = get_fact_or_default ( vcode, * rm) ?;
165
167
let rm_shifted = fail_if_missing ( ctx. shl (
166
168
& rm,
167
169
size. bits ( ) . into ( ) ,
@@ -179,8 +181,8 @@ pub(crate) fn check(ctx: &FactContext, vcode: &VCode<Inst>, inst: &Inst) -> PccR
179
181
extendop,
180
182
} if has_fact ( vcode, * rn) && has_fact ( vcode, * rm) => {
181
183
check_output ( & ctx, vcode, rd. to_reg ( ) , || {
182
- let rn = get_fact ( vcode, * rn) ?;
183
- let rm = get_fact ( vcode, * rm) ?;
184
+ let rn = get_fact_or_default ( vcode, * rn) ?;
185
+ let rm = get_fact_or_default ( vcode, * rm) ?;
184
186
let rm_extended = fail_if_missing ( extend_fact ( & ctx, rm, * extendop) ) ?;
185
187
fail_if_missing ( ctx. add ( & rn, & rm_extended, size. bits ( ) . into ( ) ) )
186
188
} )
@@ -193,7 +195,7 @@ pub(crate) fn check(ctx: &FactContext, vcode: &VCode<Inst>, inst: &Inst) -> PccR
193
195
immshift,
194
196
} if has_fact ( vcode, * rn) && has_fact ( vcode, * rn) => {
195
197
check_output ( & ctx, vcode, rd. to_reg ( ) , || {
196
- let rn = get_fact ( vcode, * rn) ?;
198
+ let rn = get_fact_or_default ( vcode, * rn) ?;
197
199
fail_if_missing ( ctx. shl ( & rn, size. bits ( ) . into ( ) , immshift. value ( ) . into ( ) ) )
198
200
} )
199
201
}
@@ -204,7 +206,7 @@ pub(crate) fn check(ctx: &FactContext, vcode: &VCode<Inst>, inst: &Inst) -> PccR
204
206
from_bits,
205
207
to_bits,
206
208
} if has_fact ( vcode, * rn) => check_output ( & ctx, vcode, rd. to_reg ( ) , || {
207
- let rn = get_fact ( vcode, * rn) ?;
209
+ let rn = get_fact_or_default ( vcode, * rn) ?;
208
210
fail_if_missing ( ctx. uextend ( & rn, ( * from_bits) . into ( ) , ( * to_bits) . into ( ) ) )
209
211
} ) ,
210
212
Inst :: AluRRR { size, rd, .. }
@@ -249,7 +251,7 @@ fn check_load(
249
251
vcode : & VCode < Inst > ,
250
252
ty : Type ,
251
253
) -> PccResult < ( ) > {
252
- let result_fact = rd. map ( |rd| get_fact ( vcode, rd ) ) . transpose ( ) ? ;
254
+ let result_fact = rd. and_then ( |rd| vcode. vreg_fact ( rd . into ( ) ) ) ;
253
255
check_addr (
254
256
ctx,
255
257
flags,
@@ -268,7 +270,7 @@ fn check_store(
268
270
vcode : & VCode < Inst > ,
269
271
ty : Type ,
270
272
) -> PccResult < ( ) > {
271
- let stored_fact = rd. map ( |rd| get_fact ( vcode, rd ) ) . transpose ( ) ? ;
273
+ let stored_fact = rd. and_then ( |rd| vcode. vreg_fact ( rd . into ( ) ) ) ;
272
274
check_addr (
273
275
ctx,
274
276
flags,
@@ -312,14 +314,14 @@ fn check_addr<'a>(
312
314
313
315
match addr {
314
316
& AMode :: RegReg { rn, rm } => {
315
- let rn = get_fact ( vcode, rn) ?;
316
- let rm = get_fact ( vcode, rm) ?;
317
+ let rn = get_fact_or_default ( vcode, rn) ?;
318
+ let rm = get_fact_or_default ( vcode, rm) ?;
317
319
let sum = fail_if_missing ( ctx. add ( & rn, & rm, 64 ) ) ?;
318
320
check ( & sum, ty)
319
321
}
320
322
& AMode :: RegScaled { rn, rm, ty } => {
321
- let rn = get_fact ( vcode, rn) ?;
322
- let rm = get_fact ( vcode, rm) ?;
323
+ let rn = get_fact_or_default ( vcode, rn) ?;
324
+ let rm = get_fact_or_default ( vcode, rm) ?;
323
325
let rm_scaled = fail_if_missing ( ctx. scale ( & rm, 64 , ty. bytes ( ) ) ) ?;
324
326
let sum = fail_if_missing ( ctx. add ( & rn, & rm_scaled, 64 ) ) ?;
325
327
check ( & sum, ty)
@@ -330,16 +332,16 @@ fn check_addr<'a>(
330
332
ty,
331
333
extendop,
332
334
} => {
333
- let rn = get_fact ( vcode, rn) ?;
334
- let rm = get_fact ( vcode, rm) ?;
335
+ let rn = get_fact_or_default ( vcode, rn) ?;
336
+ let rm = get_fact_or_default ( vcode, rm) ?;
335
337
let rm_extended = fail_if_missing ( extend_fact ( ctx, rm, extendop) ) ?;
336
338
let rm_scaled = fail_if_missing ( ctx. scale ( & rm_extended, 64 , ty. bytes ( ) ) ) ?;
337
339
let sum = fail_if_missing ( ctx. add ( & rn, & rm_scaled, 64 ) ) ?;
338
340
check ( & sum, ty)
339
341
}
340
342
& AMode :: RegExtended { rn, rm, extendop } => {
341
- let rn = get_fact ( vcode, rn) ?;
342
- let rm = get_fact ( vcode, rm) ?;
343
+ let rn = get_fact_or_default ( vcode, rn) ?;
344
+ let rm = get_fact_or_default ( vcode, rm) ?;
343
345
let rm_extended = fail_if_missing ( extend_fact ( ctx, rm, extendop) ) ?;
344
346
let sum = fail_if_missing ( ctx. add ( & rn, & rm_extended, 64 ) ) ?;
345
347
trace ! ( "rn = {rn:?} rm = {rm:?} rm_extended = {rm_extended:?} sum = {sum:?}" ) ;
@@ -348,12 +350,12 @@ fn check_addr<'a>(
348
350
Ok ( ( ) )
349
351
}
350
352
& AMode :: Unscaled { rn, simm9 } => {
351
- let rn = get_fact ( vcode, rn) ?;
353
+ let rn = get_fact_or_default ( vcode, rn) ?;
352
354
let sum = fail_if_missing ( ctx. offset ( & rn, 64 , simm9. value . into ( ) ) ) ?;
353
355
check ( & sum, ty)
354
356
}
355
357
& AMode :: UnsignedOffset { rn, uimm12 } => {
356
- let rn = get_fact ( vcode, rn) ?;
358
+ let rn = get_fact_or_default ( vcode, rn) ?;
357
359
// Safety: this will not overflow: `size` should be at
358
360
// most 32 or 64 for large vector ops, and the `uimm12`'s
359
361
// value is at most 4095.
@@ -371,7 +373,7 @@ fn check_addr<'a>(
371
373
Ok ( ( ) )
372
374
}
373
375
& AMode :: RegOffset { rn, off, .. } => {
374
- let rn = get_fact ( vcode, rn) ?;
376
+ let rn = get_fact_or_default ( vcode, rn) ?;
375
377
let sum = fail_if_missing ( ctx. offset ( & rn, 64 , off) ) ?;
376
378
check ( & sum, ty)
377
379
}
@@ -417,7 +419,7 @@ fn check_load_addr(
417
419
if !flags. checked ( ) {
418
420
return Ok ( ( ) ) ;
419
421
}
420
- let fact = get_fact ( vcode, reg) ?;
422
+ let fact = get_fact_or_default ( vcode, reg) ?;
421
423
let _output_fact = ctx. load ( fact, ty) ?;
422
424
Ok ( ( ) )
423
425
}
@@ -432,7 +434,7 @@ fn check_store_addr(
432
434
if !flags. checked ( ) {
433
435
return Ok ( ( ) ) ;
434
436
}
435
- let fact = get_fact ( vcode, reg) ?;
437
+ let fact = get_fact_or_default ( vcode, reg) ?;
436
438
let _output_fact = ctx. store ( fact, ty, None ) ?;
437
439
Ok ( ( ) )
438
440
}
0 commit comments