examine_pattern:
This is an optional function which is called when a pattern has been detected. The function allows the hypersim object to do additional checks on the pattern, for instance check patterns in subroutines which are called.
The hypersim object should return non-NULL if the pattern is considered okay and it wants to get a callback on when it is reached. If there are problems with this pattern and NULL is returned the matched pattern is removed. If the hypersim object refuses the pattern at this location, it might be detected later again, since there is no 'black-list' support.
The returned value should point to a per-loop structure, that will be passed along in the pattern_triggered() call. Patterns that does not allocate per-loop structures, should return the first argument, the pointer to the object itself.
The pattern_triggered() function is called when the first instruction in an installed pattern is reached. The cpu and the physical address which reached the pattern is supplied. This is the function where the hypersim class can do its work, such as fast-forward time.
If the hypersim object notices that it does not want to be called for this address here (preconditions will never be met for instance) it can return false. This will remove the match, but it does not prevent the pattern-matcher from trying again later. Returning true will cause the pattern_triggered() function to be called each time the pattern is reached (as long as the pattern is valid, of course).
The loop_data parameter is the per-loop data that was previously returned by the pattern in the examine_pattern() call.
pattern_invalidated is called when any of the write-protected regions associated to a found pattern are written to. This is an optional function. The per-loop user-data parameter is passed, to be properly free'd in a pattern-specific way.
SIM_INTERFACE(hypersim_pattern) { void *(*examine_pattern)(conf_object_t *obj, pattern_t *pattern, conf_object_t *cpu, logical_address_t vaddr, physical_address_t paddr); bool (*pattern_triggered)(conf_object_t *obj, pattern_t *pattern, void *loop_data, conf_object_t *cpu, physical_address_t paddr); void (*pattern_invalidated)(conf_object_t *obj, pattern_t *pattern, void *loop_data, physical_address_t paddr); }; #define HYPERSIM_PATTERN_INTERFACE "hypersim_pattern"