public static List<OpTpl> getPcodeOpTemplates(AddressFactory addrFactory,
			List<PcodeOp> pcodeOps) {
		ArrayList<OpTpl> list = new ArrayList<OpTpl>();
		HashMap<Integer, Integer> labelMap = new HashMap<Integer, Integer>(); // label offset to index map

		for (int seq = 0; seq < pcodeOps.size(); seq++) {
			PcodeOp pcodeOp = pcodeOps.get(seq);
			int opcode = pcodeOp.getOpcode();

			VarnodeTpl outputTpl = null;
			Varnode v = pcodeOp.getOutput();
			if (v != null) {
				outputTpl = getVarnodeTpl(addrFactory, v);
			}

			Varnode[] inputs = pcodeOp.getInputs();
			VarnodeTpl[] inputTpls = new VarnodeTpl[inputs.length];
			for (int i = 0; i < inputs.length; i++) {

				Varnode input = inputs[i];

				if (i == 0 && (opcode == PcodeOp.BRANCH || opcode == PcodeOp.CBRANCH)) {
					// Handle internal branch destination represented by constant destination
					if (input.isConstant()) {
						int labelOffset = seq + (int) input.getOffset();
						int labelIndex;
						if (labelMap.containsKey(labelOffset)) {
							labelIndex = labelMap.get(labelOffset);
						}
						else {
							labelIndex = labelMap.size();
							labelMap.put(labelOffset, labelIndex);
						}
						ConstTpl offsetTpl = new ConstTpl(ConstTpl.J_RELATIVE, labelIndex);
						ConstTpl spaceTpl = new ConstTpl(addrFactory.getConstantSpace());
						ConstTpl sizeTpl = new ConstTpl(ConstTpl.REAL, 8);
						inputTpls[i] = new VarnodeTpl(spaceTpl, offsetTpl, sizeTpl);
						continue;
					}
				}
				inputTpls[i] = getVarnodeTpl(addrFactory, input);
			}

			list.add(new OpTpl(opcode, outputTpl, inputTpls));
		}

		// Insert label templates from the bottom-up
		ArrayList<Integer> offsetList = new ArrayList<Integer>(labelMap.keySet());
		Collections.sort(offsetList);
		for (int i = offsetList.size() - 1; i >= 0; i--) {
			int labelOffset = offsetList.get(i);
			if (labelOffset > pcodeOps.size()) {
				// Skip jumps out of this block/program
				continue;
			}
			int labelIndex = labelMap.get(labelOffset);
			OpTpl labelTpl = getLabelOpTemplate(addrFactory, labelIndex);
			list.add(labelOffset, labelTpl);
		}

		return list;
	}
Convert flattened p-code ops into templates.

@param addrFactory the language's address factory
@param pcodeOps the p-code ops to convert
@return p-code op templates
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/pcode/PcodeFormatter.java