I think all references can be resolved during pass 2 (since it can do it recursively)? Unless you are counting each recursion as another pass.
I think pass 3 in sjasm is only for fetching actual assembled code and data emitted values? EDIT: For example, pass 3 could be used to inject a checksum of all the emitted bytes somewhere into your code since it needs to have produced the actual instructions and data before it could do that.
Could be wrong though the docs are vague about it. Mostly seems to be fetching actual emitted data and copes with bank switching etc. from a brief glance.
Some assemblers can do code manipulation on the 3rd pass (like turning absolute jumps into relative jumps - may require "laddering" jumps if they are too far apart, code reordering, optimisation etc.) but sjasmplus does not do that. Assemblers that actually do do that can be used to generate relocatable code though.
EDIT2: Someone once told me about a 0-pass assembler which emits instructions as you type them, and backfills missing references along the way. Very unusual that though