//MACRO Avl.remove Anchor, Node, WReg[8], FieldDispl= 0 //-------------------------------------------------------------------------------------------------- // // @ CopyRight Roberti & Parau Enterprises, Inc. 2021-2023 // // This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by-nd/4.0/ // or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. // //-------------------------------------------------------------------------------------------------- // // // Get load/store MIs and word length // eval(DVASM.getEnv()[5]); var ld= "L" + abiWID; var st= "S" + abiWID; var wl= abiWLen; var balanceLbl= DVASM.getNewLabel(); var leftField= FieldDispl; var parentField= wl + "+" + FieldDispl; var rightField= wl*2 + "+" + FieldDispl; // // Set up registers and addresses // var lockTmp= WReg[0]; var pFld = WReg[0]; var left= WReg[1]; var pAddr= WReg[2]; var right= WReg[3]; var tmp0= WReg[4]; var tmp1= WReg[5]; var tmp2= WReg[6]; var rNode= WReg[7]; var balWReg= "[" + WReg.slice(1, 8) + "]"; // // Generate code // \#Label DO // Start main DO loop \ #ld #left, #leftField[#Node] // Load left child addr \ #ld #pFld, #parentField[#Node] // Load parent field \ AVL.__EXTPA #pAddr, #pFld // Get parent addr \ AVL.__EXTLT #tmp0, #pFld // Get parent link type \ #ld #right, #rightField[#Node] // Load left child addr \ \ // \ // Node is leaf \ // \ IF ( #left == 0 && #right == 0 ), THEN // Handle leaf node \ \ IF ( #pAddr == 0 ), THEN // Node is root and leaf \ #st 0, #Anchor // Mark tree as empy \ BREAK // Done - tree is empy \ ENDIF \ \ IF ( #tmp0 != 0 ), THEN // Check if node is left child \ #st 0, #leftField[#pAddr] // Clear left child addr in parent \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ #st 0, #rightField[#pAddr] // Clear right child addr in parent \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ // \ // Node does not have left child \ // \ IF ( #left == 0 ), THEN // Node does not have left child \ #ld #pFld, #parentField[#right] // Load right child parent field \ \ IF ( #pAddr == 0 ), THEN // Check if node is root \ #st #right, #Anchor // Update header \ AVL.__EXTBB #pFld, #pFld // Keep only balance bits \ #st #pFld, #parentField[#right] // Store it back \ BREAK // Done - right child is new root \ ENDIF \ \ IF ( #tmp0 == 0 ), THEN // Check if right child \ #st #right, #rightField[#pAddr] // Node right child is new parent right child \ AVL.__SETPA #right, #pFld, #pFld, #pAddr,, RIGHT, CLEAR, #parentField // Link from new parent is to right child \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ #st #right, #leftField[#pAddr] // Node right child is new parent left child \ AVL.__SETPA #right, #pFld, #pFld, #pAddr,, LEFT, CLEAR, #parentField // Link from new parent is to left child \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ // \ // Node does not have right child \ // \ IF ( #right == 0 ), THEN // Node does not have right child \ #ld #pFld, #parentField[#left] // Load left child parent field \ \ IF ( #pAddr == 0 ), THEN // Check if node is root \ #st #left, #Anchor // Update header \ AVL.__EXTBB #pFld, #pFld // Keep only balance bits \ #st #pFld, #parentField[#left] // Store it back \ BREAK // Done - left child is new root \ ENDIF \ \ IF ( #tmp0 != 0 ), THEN // Check if node is left child \ #st #left, #leftField[#pAddr] // Node left child is new parent left child \ AVL.__SETPA #left, #pFld, #pFld, #pAddr,, LEFT, CLEAR, #parentField // Link from new parent is to left child \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ #st #left, #rightField[#pAddr] // Node left child is new parent right child \ AVL.__SETPA #left, #pFld, #pFld, #pAddr,, RIGHT, CLEAR, #parentField // Link from new parent is to right child \ GOTO #balanceLbl // Process balancing \ ENDIF \ \ // \ // Node has both left and right child \ // \ AVL.__EXTBB #tmp1, #pFld // Get balance bits \ \ // \ // Use left subtree \ // \ IF ( #tmp1 != 0 ), THEN // Use left subtree since it is deeper or even \ MV #rNode, #left // Copy left child to prime the loop \ WHILE // Start loop to find right most node in subtree \ #ld #tmp1, #rightField[#rNode] // Load right child addr \ IF ( #tmp1 == 0 ), BREAK // Most right node in left subtree found \ MV #rNode, #tmp1 // Copy node addr \ ENDWHILE \ \ IF ( #pAddr == 0 ), THEN // Check if node is root \ #st #rNode, #Anchor // Update header addr of root node \