//MACRO Avl.__balnc Type, Anchor, PFld, FieldDispl, WReg[7] //-------------------------------------------------------------------------------------------------- // // @ 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 leftField= FieldDispl; var parentField= wl + "+" + FieldDispl; var rightField= wl*2 + "+" + FieldDispl; var complRotLabel= DVASM.getNewLabel(); // // Validate Type and WReg parameters // Type= Type.toUpperCase(); var typeNdx= ["INSERT", "REMOVE"].indexOf(Type); if (typeNdx < 0) return DVASM.putError("Positional parameter Type [%s] is invalid", Type.toUpperCase()); var balAddSub= ["ADD", "SUB"][typeNdx]; var pFld= PFld; var bNode= WReg[0]; var aNode= WReg[1]; var cNode= WReg[2]; var tmp0= WReg[3]; var tmp1= WReg[4]; var tmp2= WReg[5]; var tmp3= WReg[6]; var balance= WReg[6]; \ // \ // Balance the tree \ // \#Label AVL.__EXTPA #aNode, #pFld // Set up parent addr for WHILE loop \ \ DO // Start balance loop \ AVL.__EXTLT #tmp0, #pFld // Extract link type from parent \ SRLI #tmp0, 1 // Convert link type \ ADDI #tmp0, -1 // ... to +/- 1 to be subtracted from balance \ #ld #pFld, #parentField[#aNode] // Get parent field \ AVL.__EXTBL #balance, #pFld // Get balance of parent of deleted node \ #balAddSub #balance, #tmp0 // Add (insert) Subtract (remove) link for new balance \ \ // \ // Check if left rotation \ // \ LI #tmp0, 1 // Load compare constant \ IF ( #balance > #tmp0 ), THEN // Handle left substree too high \ #ld #bNode, #leftField[#aNode] // Load B node addr \ #ld #cNode, #rightField[#bNode] // Get C node addr \ #ld #tmp3, #parentField[#bNode] // get B node parent field \ AVL.__EXTBL #tmp3, #tmp3 // Get B node balance \ \ // \ // LL rotation - Top node is A, left child is B, right child of B node is C node if any \ // \ IF ( #tmp3 >= 0 ), THEN // LL rotation if >= 0 \ #st #cNode, #leftField[#aNode] // Make C node right child of A node \ IF ( #cNode != 0 ), THEN // Check if C node exists \ #ld #tmp0, #parentField[#cNode] // Get parent field of C node \ AVL.__SETPA #cNode, #tmp0, #tmp0, #aNode,, LEFT, CLEAR, #parentField // Set C node parent to A node - left link \ ENDIF // // Code is slightly different between insert and remove - when insert balance for B cannot be zero // if (Type === "INSERT") { \ AVL.__SETPA #aNode, #tmp0, #bNode,, EVEN, RIGHT, NOCLEAR, #parentField // Set balance even - right link for A node \ AVL.__SETPA #bNode, #pFld, #pFld,, EVEN,, CLEAR, #parentField // Set balance even - A node parent for B node } else { \ IF ( #tmp3 != 0 ), THEN // Check if B node balance is not even \ AVL.__SETPA #aNode, #tmp0, #bNode,, EVEN, RIGHT, NOCLEAR, #parentField // Set balance even - right link for A node \ AVL.__SETPA #bNode, #pFld, #pFld,, EVEN,, CLEAR, #parentField // Set balance even - A node parent for B node \ 0 ) // Check if C node balance is high on left \ AVL.__SETPA , #tmp1, #cNode,, EVEN, LEFT, NOCLEAR, #parentField // Set B node parent even/left \ AVL.__SETPA , #tmp2, #cNode,, MINUS, RIGHT, NOCLEAR, #parentField // Set A node parent minus/right \ 0 ), THEN // Check if left link \ #st #aNode, #leftField[#tmp1] // Set new top node as left child of parent \