I've been working on a device that has P2 talk to an SPI peripheral that has its 3V logic levels shifted up by 2V (i.e. LO=2V, HI=5V).
P2's IO is powered from GND@0V, VCCIO@3.3V, the SPI peripheral is at GND@2V, VCC@5V. The logic levels are shifted by 2V between the devices. It turns out that a very simple circuit can leverage P2's current sink mode and make it work in either direction.
P2 IO pin is connected to the anode of a 2V Zener diode paralleled with a 0.1uF capacitor. The cathode goes to the SPI peripheral pin. A 1k pullup is needed on the SPI perhipheral's input/bidirectional pins only. The principle of operation is that the Zener maintains ~2V DC translation shift voltage across the capacitor, the latter otherwise appearing as a short to rising/falling signal edges.
P2 outputs are driven hard (HHHLLL=%000_000), while P2 inputs are driven low (DRVL) with a 100uA current sink (LLL=%101), providing bias current. This ensures proper biasing of the Zener, and thus the level translation shift action is maintained. The pull-up drops 0.1V at 0.1mA bias current.
The cost is <= $0.10 per signal in high quantity SMT. The impedance of the Zener doesn't matter much, since the capacitor bypasses the fast logic edges around it.
For slower inputs, using the programmable comparator and a series current limiting resistor all by itself is sufficient. That's the P=%110x_CDDDDDDDD pin mode. The SPI peripheral's CMOS 50% logic threshold voltage is at (2V+5V)/2=3.5V - above P2's VCCIO, but we can use 33% threshold level instead, and that would be 2V + 0.33*3V = 3.0V. That means the DAC level 255*3.0/3.3=232 = %1110_1001, so P=%110x_11101001. This will work OK as long as the RC time constant is acceptable (R being the series resistor value, and C being the P2 input pin's capacitance).